2010-05-05 144 views
3

我有一个奇怪的问题,我从来没有真正前expirienced这一点,这里是服务器的代码(客户端是火狐在这种情况下),我的方式创建它:监听套接字

_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
_Socket.Bind(new IPEndPoint(Settings.IP, Settings.Port)); 
_Socket.Listen(1000); 
_Socket.Blocking = false; 

的方式,我接受连接:

while(_IsWorking) 
{ 
    if(listener.Socket.Poll(-1, SelectMode.SelectRead)) 
    { 
     Socket clientSocket = listener.Socket.Accept(); 
     clientSocket.Blocking = false; 
     clientSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); 
    } 
} 

所以我很期待它listener.Socket.Poll挂直到新的连接来了,但是第一次来后永远挂在民意调查。我试图用更小的延迟来轮询它,比如说10微秒,然后它永远不会在SelectMode.SelectRead中进行。我想这可能以某种方式与客户端的套接字重用相关?也许我不会关闭客户端套接字并且客户端(firefox)决定使用旧的套接字?

我断开客户端套接字是这样的:

Context.Socket.Shutdown(SocketShutdown.Both); // context is just a wrapper around socket 
Context.Socket.Close(); 

什么可能导致这个问题?

回答

1

您是否考虑过异步接受远程客户端? I answered a similar question最近在TCPListener,但在Socket类别上可以使用相同的模式。

我从来没有见过此之前用来检查客户端可用来连接:

listener.Socket.Poll(-1, SelectMode.SelectRead)) 

我一看Sockets.TCPListener.Pending()方法中使用.NET反射器和他们有此相反,也许你可以试试它:

public bool Pending() 
{ 
    if (!this.m_Active) 
    { 
     throw new InvalidOperationException(SR.GetString("net_stopped")); 
    } 
    return this.m_ServerSocket.Poll(0, SelectMode.SelectRead); 
} 

只要记住,根据MSDN的TCPListener.Pending()方法是非阻塞所以不知道,如果它可以帮助你100%?

+0

我想我找到了我描述的behavour的原因,这是因为我没有断开客户端套接字处理后,以及由于某种原因无法建立新的连接,我想这是一些如何与客户端(在这种情况下,Firefox)希望使用一个套接字(如果它没有被服务器关闭),直到可能。 – hoodoos 2010-05-06 10:15:31

+0

实际上,你提到的问题中的那个人完全错了:)而且我实际上没有提到他在等待检查之间有睡眠,我真的不知道他是以什么目的以非阻塞的方式进行听力检查。 – hoodoos 2010-05-06 10:18:04