动态修改TCPClient端口号

本文关键字:口号 TCPClient 修改 动态 | 更新日期: 2023-09-27 17:50:11

假设您有以下代码:

 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?
        }
    }

看代码,似乎客户端的本地端点服务器的远程端点似乎改变到另一个端口然而,在每种情况下,相反的情况都是相同。

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}

动态修改TCPClient端口号

你对这个问题的看法是错误的;生成一个新的线程来处理TcpClient,然后循环回TcpListener.AcceptTcpClient()需要你改变端口;一个服务器可以在同一个套接字上获得多个连接。

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

你的代码在某个地方出了问题。您的"每个连接一个线程"代码并不理想(每个连接一个线程远远超过需要),但它是一种快速而肮脏的方式,工作得很好。

如何构造侦听器?你和客户在做什么?接下来的连接到底发生了什么?

我同意其他人的观点,你可能想看看异步方法,而不是为每个连接使用单独的线程,或者至少是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);
    }
}