为什么Scoket只工作一次? [英] Why the Scoket works only once ?

查看:90
本文介绍了为什么Scoket只工作一次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试一个演示项目:

http://code.msdn.microsoft.com/Communication-through-91a2582b

我做了一些小事在VS 2008中更改。服务器代​​码如下:

I am trying the a demo project from:
http://code.msdn.microsoft.com/Communication-through-91a2582b
I have made some small change in VS 2008. The server code is following:

using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace TCP_Socket_Server
{
    public partial class TCPSocketServer : Form
    {
        SocketPermission permission;
        Socket sListener;
        IPEndPoint ipEndPoint;
        Socket handler;
        private TextBox tbAux = new TextBox();

        public TCPSocketServer()
        {
            InitializeComponent();

            tbAux.TextChanged += tbAux_SelectionChanged;

            button_ServerStart.Enabled = true;
            button_Send.Enabled = false;
            button_Disconnect.Enabled = false;
            textBox_MessageReceived.Enabled = false;
            textBox_Message2Client.Enabled = false;
        }

        private void tbAux_SelectionChanged(object sender, EventArgs e)
        {
            BeginInvoke((ThreadStart)delegate()
            {
                textBox_MessageReceived.Text = tbAux.Text;
                label_MessageReceived.Text = "Received Message(" + (2*tbAux.Text.Length).ToString() +"Byte)";
            }
            );
        }

        private void button_ServerStart_Click(object sender, EventArgs e)
        {
            int servPort = (textBox_Port.Text.Length != 0) ? Int32.Parse(textBox_Port.Text) : 8821;
            try
            {
                // Creates one SocketPermission object for access restrictions
                permission = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", servPort );

                // Listening Socket object 
                sListener = null;

                // Ensures the code to have permission to access a Socket 
                permission.Demand();

                // Resolves a host name to an IPHostEntry instance 
                IPHostEntry ipHost = Dns.GetHostEntry("");

                // Gets first IP address associated with a localhost 
                IPAddress ipAddr = ipHost.AddressList[0];

                // Creates a network endpoint 
                ipEndPoint = new IPEndPoint(ipAddr, servPort);

                // Create one Socket object to listen the incoming connection 
                sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp );

                sListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

                // Associates a Socket with a local endpoint 
                sListener.Bind(ipEndPoint);

                label_ServerState.Text = "Server Started:" + ipEndPoint.Address + ":" + ipEndPoint.Port;;
                label_ServerState.ForeColor = Color.Blue;
                button_Send.Enabled = true;
                button_Disconnect.Enabled = true;
                textBox_MessageReceived.Enabled = true;
                textBox_Message2Client.Enabled = true;

                // Places a Socket in a listening state and specifies the maximum 
                // Length of the pending connections queue 
                sListener.Listen(10);

                // Begins an asynchronous operation to accept an attempt 
                AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
                sListener.BeginAccept(aCallback, sListener);
                button_ServerStart.Enabled = false;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        public void AcceptCallback(IAsyncResult ar)
        {
            Socket listener = null;

            // A new Socket to handle remote host communication 
            Socket handler = null;
            try
            {
                // Receiving byte array 
                byte[] buffer = new byte[1024];
                // Get Listening Socket object 
                listener = (Socket)ar.AsyncState;
                // Create a new socket 
                handler = listener.EndAccept(ar);

                // Using the Nagle algorithm 
                handler.NoDelay = false;

                // Creates one object array for passing data 
                object[] obj = new object[2];
                obj[0] = buffer;
                obj[1] = handler;

                // Begins to asynchronously receive data 
                handler.BeginReceive(buffer,  0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);

                // Begins an asynchronous operation to accept an attempt 
                AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
                listener.BeginAccept(aCallback, listener);
            }
            catch (Exception exc) { MessageBox.Show(exc.ToString()); }
        }

        public void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Fetch a user-defined object that contains information 
                object[] obj = new object[2];
                obj = (object[]) ar.AsyncState;

                // Received byte array 
                byte[] buffer = (byte[]) obj[0];

                // A Socket to handle remote host communication. 
                handler = (Socket) obj[1];

                // Received message 
                string content = string.Empty;

                // The number of bytes received. 
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    content += Encoding.Unicode.GetString(buffer, 0, bytesRead);

                    // If message contains "<Client Quit>", finish receiving
                    if (content.IndexOf("<Client Quit>") > -1)
                    {
                        // Convert byte array to string
                        string str = content.Substring(0, content.LastIndexOf("<Client Quit>"));
                    }
                    else
                    {
                        // Continues to asynchronously receive data
                        byte[] buffernew = new byte[1024];
                        obj[0] = buffernew;
                        obj[1] = handler;
                        handler.BeginReceive(buffernew, 0, buffernew.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
                    }

                    //this is used because the UI couldn't be accessed from an external Thread
                    BeginInvoke((ThreadStart)delegate()
                    {
                        tbAux.Text = content.Replace(@"<Client Quit>", "");
                    });
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        private void button_Send_Click(object sender, EventArgs e)
        {
            try
            {
                // Convert byte array to string 
                string str = textBox_Message2Client.Text + @"<Server Quit>";

                // Prepare the reply message 
                byte[] byteData =Encoding.Unicode.GetBytes(str);

                // Sends data asynchronously to a connected Socket 
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);

                label_Message2Client.Text = "Message Sent by Server(" + (byteData.Length - 26).ToString() + "Byte)";

            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        public void SendCallback(IAsyncResult ar)
        {
            try
            {
                // A Socket which has sent the data to remote host 
                Socket handler = (Socket)ar.AsyncState;
            }
            catch (Exception exc) { MessageBox.Show(exc.ToString()); }
        }

        private void button_Disconnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (sListener.Connected)
                {
                    sListener.Shutdown(SocketShutdown.Both);
                    sListener.Close();
                }

                button_ServerStart.Enabled = true;
                button_Send.Enabled = false;
                button_Disconnect.Enabled = false;
                label_Message2Client.Text = "Message to Client" ;
                label_MessageReceived.Text = "Received Message";
                textBox_MessageReceived.Text = string.Empty;
                textBox_MessageReceived.Enabled = false;
                textBox_Message2Client.Text = string.Empty;
                textBox_Message2Client.Enabled = false;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }
    }
}



客户代码为:


The client code is:

using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace TCP_Socket_Client
{
    public partial class TCPSocketClient : Form
    {
        // Receiving byte array  
        byte[] bytes = new byte[1024];
        Socket senderSock;
        private TextBox tbAux = new TextBox();

        public TCPSocketClient()
        {
            InitializeComponent();

            tbAux.TextChanged += tbAux_SelectionChanged;

            ipAddressControl_Server.Focus();
            button_Send.Enabled = false;
            button_Disconnect.Enabled = false;
            textBox_Message2Send.Enabled = false;
            textBox_MessageReceived.Enabled = false;
        }

        private void tbAux_SelectionChanged(object sender, EventArgs e)
        {
            BeginInvoke((ThreadStart)delegate()
            {
                textBox_MessageReceived.Text = tbAux.Text;
                label_MessageReceived.Text = "Message from Server(" + (2 * tbAux.Text.Length).ToString() + "Byte)";
            }
            );
        }

        private void button_Connect2Server_Click(object sender, EventArgs e)
        {
            int servPort = (textBox_Port.Text.Length != 0) ? Int32.Parse(textBox_Port.Text) : 8821;

            try
            {
                // Create one SocketPermission for socket access restrictions 
                SocketPermission permission = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, ipAddressControl_Server.Text, servPort);

                // Ensures the code to have permission to access a Socket 
                permission.Demand();

                // Gets first IP address associated with a localhost 
                IPAddress ipAddr = IPAddress.Parse(ipAddressControl_Server.Text);

                // Creates a network endpoint 
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, servPort);

                // Create one Socket object to setup Tcp connection 
                senderSock = new Socket(ipAddr.AddressFamily,  SocketType.Stream, ProtocolType.Tcp);

                senderSock.NoDelay = false; // Using the Nagle algorithm 

                // Establishes a connection to a remote host 
                senderSock.Connect(ipEndPoint);
                label_ConnectionState.Text = "Already Connectted to" + senderSock.RemoteEndPoint;
                label_ConnectionState.ForeColor = Color.Blue;
                button_Connect2Server.Enabled = false;
                button_Send.Enabled = true;
                button_Disconnect.Enabled = true;
                textBox_Message2Send.Enabled = true;
                textBox_MessageReceived.Enabled = true;

                new Thread(new ThreadStart(delegate{ReceiveDataFromServer();})).Start();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        private void button_Send_Click(object sender, EventArgs e)
        {
            try
            {
                //<Client Quit> is the sign for end of data 
                string theMessageToSend = textBox_Message2Send.Text;
                byte[] msg = Encoding.Unicode.GetBytes(theMessageToSend + @"<Client Quit>");

                // Sends data to a connected Socket. 
                int bytesSend = senderSock.Send(msg) - 26; //"<Client Quit>" is 26Byte

                label_Message2Server.Text = "Message to Server(" + bytesSend.ToString() + "Byte)";
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        private void ReceiveDataFromServer()
        {
            try
            {
                // Receives data from a bound Socket. 
                int bytesRec = senderSock.Receive(bytes);

                // Converts byte array to string 
                String theMessageToReceive = Encoding.Unicode.GetString(bytes, 0, bytesRec);

                // Continues to read the data till data isn't available 
                while (senderSock.Available > 0)
                {
                    bytesRec = senderSock.Receive(bytes);
                    theMessageToReceive += Encoding.Unicode.GetString(bytes, 0, bytesRec);
                }

                tbAux.Text = theMessageToReceive.Replace(@"<Server Quit>", "");
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

        private void button_Disconnect_Click(object sender, EventArgs e)
        {
            try
            {
                // Disables sends and receives on a Socket. 
                senderSock.Shutdown(SocketShutdown.Both);

                //Closes the Socket connection and releases all resources 
                senderSock.Close();

                button_Connect2Server.Enabled = true;
                button_Send.Enabled = false;
                button_Disconnect.Enabled = false;
                label_ConnectionState.Text = "No Connection to Server";
                label_ConnectionState.ForeColor = Color.Red;
                textBox_Message2Send.Enabled = false;
                textBox_Message2Send.Text = string.Empty;
                textBox_MessageReceived.Enabled = false;
                textBox_MessageReceived.Text = string.Empty;
                label_Message2Server.Text = "Message to Server";
                label_MessageReceived.Text = "Message from Server";
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }
    }
}



现在,我有两个问题。一个是每次启动并从客户端发送第一条消息后,服务器会显示它,但如果发送了另一条消息,则服务器显示第一条消息而不是第二条消息。客户也是如此。另一种是当服务器关闭连接时,客户端仍然显示已连接的状态。感谢您的任何建议。


Now, I have two problems. One is that each time after it''s start and a first message was sent from the client, the server shows it, but if aniother message was sent then, the server shows the first not the second message. So does the client. The other is that when the server close the connection, the client still shows a connectted already state. Thanks for any suggestion。

推荐答案

由于这是一个Microsoft演示和文章,您应该将此问题发布给文章的作者。
Since this is a Microsoft demo and article you should be posting this question to the author of the article.


这篇关于为什么Scoket只工作一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆