读书人

用thread开启线程和异步接收socket的疑

发布时间: 2012-04-10 21:03:56 作者: rapoo

用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);} 

读书人网 >C#

热点推荐