首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态更改TCPClient端口

动态更改TCPClient端口
EN

Stack Overflow用户
提问于 2011-04-15 05:02:17
回答 2查看 5.4K关注 0票数 0

假设您有以下代码。

代码语言:javascript
复制
 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更改它正在运行的端口,还是通过向客户端发送一个新的端口号并告诉它重新连接来实现这种功能的唯一方法呢?

代码语言:javascript
复制
    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?
        }
    }

在查看代码时,似乎客户机的本地端点和服务器的远程端点似乎更改为不同的端口,但在每种情况下,相反的情况都保持不变。

代码语言:javascript
复制
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}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-15 06:51:43

这里的问题是不正确的;生成一个新线程来处理TcpClient,然后循环回TcpListener.AcceptTcpClient()并不需要您更改端口;单个服务器可以在同一个套接字上获得多个连接。

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

在某个地方,您的代码出现了其他问题。您的“每个连接线程”代码并不理想(每个连接的线程比所需的要多得多),但这是一种快速和肮脏的方式,工作正常。

你是如何构造听者的?你要和客户做什么?接下来的连接到底发生了什么呢?

票数 3
EN

Stack Overflow用户

发布于 2011-04-15 07:22:54

我同意其他人的观点,即您可能希望查看异步方法,而不是为每个连接使用单独的线程,或者至少要使用BackgroundWorker.至于正在发生的事情,您是否尝试过调试,以确保AcceptTcpClient调用中有一个线程被卡住了?您可以尝试在Start()调用中指定一个较高的待办事项。它是否具有作用域,或者因为没有维护引用而对线程进行垃圾收集?如果你把一个Thread.Sleep(10000)放在你的循环的末尾,10秒后你能连接吗?如果您尝试使用命令行telnet连接到端口(即"telnet localhost 9999"),屏幕是否空白显示它已连接?

您可以尝试添加一个哈希表来存储线程并在退出时删除它们,这增加了拥有一个线程列表并能够关闭连接并杀死它们的好处.

代码语言:javascript
复制
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);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5672575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档