2011-04-15 68 views
0

可以说你有以下代码。动态更改TCPClient端口

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 
    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication)); 
    clientThread.Start(client); 
} 


private void HandleClientCommunication(object client) 
{ 
    using (TcpClient tcpClient = (TcpClient) client) 
    { 
     //Do my work 
    } 
} 

与这种实现的问题是,无论端口我在初始连接使用了,然后在客户端通信使用,并为此(尽管事实的TCPListener仍然听这将是无法接受其他连接直到港口被释放)。

有没有办法告诉tcpClient改变它正在工作的端口,或者是通过向客户端发回一个新的端口号并告诉它重新连接来实现这种功能的唯一方法?

IE: 

    TcpListener1.AcceptTcpClient(); //Wait 
    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication));  
    clientThread.Start(client); 

    private void HandleClientCommunication(object client) 
    { 
     using (TcpClient tcpClient = (TcpClient) client) 
     { 
      //Generate random port number send back to client and create another thread with a new tcpListener and wait again? 
     } 
    } 

看代码似乎 客户端的localendpoint和 的remoteendpoint服务器 似乎更改为不同的端口 但在每种情况下,逆停留在 相同。

IE: 
Started server tcpListener on 121 
ClientLocalEndPoint: {127.0.0.1:1380} 
ClientRemoteEndPoint: {127.0.0.1:121} 
ServerLocalEndPoint: {127.0.0.1:121} 
ServerRemoteEndPoint: {127.0.0.1:1380} 
+0

检查“接受者”和“事件循环”模式 – bobah 2011-04-15 07:13:01

回答

3

你是不正确的关于这里的问题;产生一个新的线程来处理TcpClient,然后循环回到TcpListener.AcceptTcpClient()确实不是要求您更改端口;一台服务器可以连接多个连接到同一个套接字。

否则,Web服务器将如何同时处理多个用户?

其他地方的代码出错了。你的“每个连接线程”代码并不理想(每个连接的线程远远超过需要的),但它是一种快速和肮脏的方式,工作得很好。

你是如何构造监听器的?你在跟客户做什么?以后的连接究竟发生了什么?

+0

我从来没有想过关于Web服务器上的观点 - 我知道很愚蠢。 PS:代码完全按照预期工作。我从来没有用两个客户端进行测试,因为我确信它不会起作用。 – 2011-04-15 16:00:32

1

我同意别人的看法,你可能想看看异步方法,而不是为每个连接使用单独的线程,或者至少使用BackgroundWorker ......至于发生了什么,你是否尝试调试确保你有一个线程停留在AcceptTcpClient调用?您可以尝试在Start()调用中指定高积压量。它可能是范围的东西,也许垃圾收集你的线程,因为你不保留一个参考它?如果在循环结束时放置Thread.Sleep(10000),可以在10秒后连接吗?如果尝试使用命令行telnet连接到端口(即“telnet localhost 9999”),屏幕空白显示它已连接?

你可以尝试像添加一个哈希表来存储你的线程并删除它们在退出这增加了让他们的列表,并能够关闭连接并杀死他们的利益......

Dictionary<TcpClient, Thread> _threads = new Dictionary<TcpClient, Thread>(); 
object _lockObject = new object(); 

void AddThread(TcpClient client, Thread thread) 
{ 
    lock (_lockObject) 
    { 
     _threads.Add(client, thread); 
    } 
} 

void RemoveThread(TcpClient client) 
{ 
    lock (_lockObject) 
    { 
     _threads.Remove(client); 
    } 

} 

void YourMainMethod() 
{ 
    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 
     Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication)); 
     AddThread(client, clientThread); 
     clientThread.Start(client); 
    } 
} 


private void HandleClientCommunication(object client) 
{ 
    try 
    { 
     using (TcpClient tcpClient = (TcpClient) client) 
     { 
      //Do my work 
     } 
    } catch (Exception) 
    { 
     // so program doesn't crash 
    } 
    finally 
    { 
     RemoveThread((TcpClient)client); 
    } 
}