用thread开启线程和异步接收socket的疑问?
private Socket socket;
private Socket acceptSocket;  
protected void Listen()
         {
             socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             socket.Bind(new IPEndPoint(IPAddress.Any, 2000));
             socket.Listen(0);
             while (true)
             {
                 //acceptSocket = socket.Accept();
                 //Thread thread = new Thread(new ThreadStart(BeginTempSocket));
                 //thread.Start();
                 //下面使用非阻塞式来接收客户端的请求,程序会有点卡,并且会报outofMemory的错误
                 socket.BeginAccept(new AsyncCallback(AsyncBeginTempSocket), socket);
             }
         }
protected void AsyncBeginTempSocket(IAsyncResult ar)
         {
          Socket s = (Socket)ar.AsyncState;
          acceptSocket = s.EndAccept(ar);
          ............接收数据
          }
protected void BeginTempSocket()
         {
         ............接收数据
          }
如上的代码:如果使用acceptSocket = socket.Accept();同步接收客户端,然后开启thread来接收数据,程序正常,很流畅;
但是如果使用socket.BeginAccept(new AsyncCallback(AsyncBeginTempSocket), socket);异步接收socket客户端的话,程序有点卡,并且连接了几次,就报outofMemory的错误了!具体的接收数据的代码都是一样的。
为什么呢?是不是异步的地方有哪里写得不对啊?
谢谢!
------解决方案--------------------BeginAccept很快就返回了。在循环中调用它,会造成很多很多很多个连接等待,不是好的选择。
由于OS会提供排队缓冲区,一般用一个线程进行Accept就可以了。连接后的具体通信再由不同的线程来处理(或进行异步操作)。
C# code
void Listen()
{
  while (true)
  {
    Socket s = socket.Accept();
    ThreadPool.QueueUserWorkItem(Worker, s);
  }
}
void Worker(object state)
{
   Socket soket = state as Socket;
   //...
}
------解决方案--------------------
使用tcplistener和tcpclient会简单一些,而且可以使用到IOCP。
就算如你的代码那样使用sockey服务的主程序,大致(按照你的代码)就是这样:C# code
protected void Listen()
{
  socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  socket.Bind(new IPEndPoint(IPAddress.Any, 2000));
  socket.Listen(int.MaxValue);
  socket.BeginAccept(new AsyncCallback(AsyncAcceptSocket), null);
}