我的TCPListener配置如下:
this.tcpListener = new TcpListener(IPAddress.Any, config.portNum);
然后我(使用线程)设置一个这样的监听器函数:
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
ThreadStart starter = delegate { HandleClientComm(client, this.DBGrid); };
Thread thread = new Thread(starter);
thread.Start();
}
}
第一次使用它,第二次触发它,我收到此错误消息:
通常只对每个套接字地址(协议/网络地址/端口)使用一次 允许
在线程内部有一个关闭的调用:
tcpClient.Close();
但它似乎没有释放端口,任何建议?
答案 0 :(得分:2)
如果您反复拨打ListenForClients
,那么这就是问题的根源,而不是客户端连接没有Close()
正确。
传统上,一个线程将处理打开主套接字并接受'子'连接套接字。所以你的ListenForClients
应该在主服务器线程中,并且每个应用程序只调用一次。
更多信息:
this.tcpListener.Start();
在您指定的端口创建一个监听的监听。每个客户连接,
TcpClient client = this.tcpListener.AcceptTcpClient();
行将创建一个连接的新套接字,并且位于完全不同的端口上。因此,关闭客户端时,根本不会释放主套接字。
来自http://en.wikipedia.org/wiki/Internet_socket#Socket_states_and_the_client-server_model
提供应用程序服务的计算机进程称为服务器,并在启动时创建处于侦听状态的套接字。这些套接字正在等待来自客户端程序的举措。对于侦听TCP套接字,netstat提供的远程地址可以表示为0.0.0.0,远程端口号可以表示为0.
TCP服务器可以通过为每个客户端创建子进程并在子进程和客户端之间建立TCP连接来同时为多个客户端提供服务。为每个连接创建唯一的专用套接字。这些处于已建立状态,当与远程套接字建立套接字到套接字虚拟连接或虚拟电路(VC)(也称为TCP会话)时,提供双工字节流。
答案 1 :(得分:2)
问题在于tcpListener.Start()。您不能在同一端口上拥有2个侦听器。 ListenForClients方法应该只在您的应用程序中调用一次