none
Socket服务端异步接收数据的问题 RRS feed

  • 问题

  • Byte[] data = new Byte[1024];//用于接受数据
    public void SocketReceive(Socket socket)
            {
                //Byte[] data = new Byte[1024];
                socket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), socket);
            }
    
    public void OnReceiveCallback(IAsyncResult ar)
            {
                Socket socket = (Socket)ar.AsyncState;
                int dataLen = socket.EndReceive(ar);
                try
                {
                    if (dataLen > 0)
                    {
                        string ClientMessage = Encoding.UTF8.GetString(data, 0, dataLen);
                        Console.WriteLine("FromClient:" + ClientMessage);
                        //ToDo 解析业务处理
                        //1、转发给别的Client
    
                        //2、处理业务返还给Client
                        SocketSend(socket);
                        socket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), socket);
                    }
                    else
                    {
                        Console.WriteLine("Client: " + socket.RemoteEndPoint + " Disconnected……");
                        socket.Shutdown(SocketShutdown.Both);
                        socket.Close();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }

    请教问题一:服务器端在异步接受客户端传来的数据时,socket.BeginReceive(data,....)中的data需要声明在方法外,是个全局变量。那么当多个客户端同时连接服务端并发送数据时,是不是会破坏data的数据完整性,使得服务端接收错误的数据呢?应该怎么避免呢?或者说异步接收客户端数据时应该如何保证数据的完整性呢?有什么方法和思路吗?

    请教问题二:还有些问题不太清楚,以下是我个人理解,不知道对不对,希望大家可以给予解答和指点。

    1、所谓的使用Socket异步通信是防止Socket线程或者主线程的阻塞,造成假死或者资源浪费。(理解是否正确?)

    2、所谓的异步通信是依赖多线程实现的。但是对于服务器端,始终是那唯一的一个socket来监听所有的客户端连接,只是当收到连接时起一个线程来进行接受或者发送工作。对于所有的客户端请求依旧是按顺序一个一个处理,而不是同时处理多个。还是说类似于使用了线程池为每一个需要操作的客户端启用一个线程,同时处理多个客户端?(哪个理解是正确的呢?)

    3、对于多客户端与服务器通信的问题,如何高效的解决两端的通信问题。在服务器端实例多个socket来监听同一个通信端口是否可行呢?

    4、socket.Send(...)是同步通信,socket.BeginSend(...)是异步通信。如果使用线程池ThreadPool.QueueUserWorkItem(new WaitCallback(SendData),data),在SendData方法中执行socket.Send(data,...)方法是不是也可以达到socket.BeginSend(...)的效果呢?

    刚刚接触网络通信,还有很多不解的地方,希望大家可以耐心的给予帮助,谢谢!

    2013年6月19日 9:47

答案

  • Hi,

    >>是不是会破坏data的数据完整性,使得服务端接收错误的数据呢

    不会,每次都会将原来的数据覆盖掉。要保证你能接受到完整的数据,你应该自己处理接受到的数据。这里服务器端不会接收到错误数据。

    >>1、所谓的使用Socket异步通信是防止Socket线程或者主线程的阻塞,造成假死或者资源浪费

    对,这正是异步本身的思想。

    >>对于所有的客户端请求依旧是按顺序一个一个处理,而不是同时处理多个。

    对的。

    >>在服务器端实例多个socket来监听同一个通信端口是否可行呢

    不可以。

    >>SendData方法中执行socket.Send(data,...)方法是不是也可以达到socket.BeginSend(...)的效果呢?

    对的。


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年6月20日 5:33
    版主