none
怎样修改一个正在运行的socket的端口? RRS feed

  • 问题

  • Thread myThread = new Thread(new ThreadStart(StartListening));

    myThread.Start();

    我先用这样一段代码开启一个监听线程;线程代码是:

    int port = 1000;//端口默认值

    private void StartListening()

    {

    IPAddress hostIP = Program.GetHostIP();//获取本机IP

    TcpListener Listen = new TcpListener(hostIP,port);

    Listen.Start();

    ...............//这里就是有连接就转到数据接收过程,不是主要问题就不写了。

    }

    我想要做的就是:在程序运行的时候,我修改了port的值,怎么能让监听线程改为监听新的端口呢?

    2013年1月31日 1:56

答案

  • http://msdn.microsoft.com/zh-cn/library/7a2f3ay4(v=VS.80).aspx

    我建议你先启动新端口的监听线程,然后再终止监听旧端口的线程。因为跟据线程的特性,终止的过程可能需要一定时间。

    简单的方式是,自动重新启动你的程序,然后读取新的端口值监听。

    • 已标记为答案 Mclovin 2013年1月31日 3:37
    2013年1月31日 2:04
  • 我们以这篇文章中的代码来说明:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.tcplistener(v=VS.80).aspx

    你点击重启后,先需要停止旧的监听端口,那么你需要在代码中的两个 while 循环中都设置标志来判断是否需要继续读取数据,你可以使用一个全局的变量,也可以使用EVENT_HANDLE来控制,通过WaitFor来控制两个 while 循环是执行还是终端,只所以在停止线程前需要先终止线程执行体的方法,是因为线程除了由进程控制生命周期外,就完全依赖它所执行的方法体了。当两个 while 结束后,你就需要执行 server.Stop() 来停止监听。一个简便的方式是当两个 while 被要求中断时抛出异常,那么线程就会立即终止,同时 finanly 中的代码保证 server.Stop() 总是会被调用。

    线程一旦终止后是无法再重新启动的,你需要新建一个线程来启动你新端口的监听。


    重启整个进程(或者可以用卸载应用程序域来实现)前,先把新端口写入磁盘,或者作为启动参数,启动的进程通过磁盘或者启动参数来读入新的端口值。
    • 已编辑 Skyseer 2013年1月31日 2:46
    • 已标记为答案 Mclovin 2013年1月31日 3:37
    2013年1月31日 2:35

全部回复

  • 类似于让线程停止然后重新运行。
    2013年1月31日 1:58
  • http://msdn.microsoft.com/zh-cn/library/7a2f3ay4(v=VS.80).aspx

    我建议你先启动新端口的监听线程,然后再终止监听旧端口的线程。因为跟据线程的特性,终止的过程可能需要一定时间。

    简单的方式是,自动重新启动你的程序,然后读取新的端口值监听。

    • 已标记为答案 Mclovin 2013年1月31日 3:37
    2013年1月31日 2:04
  • http://msdn.microsoft.com/zh-cn/library/7a2f3ay4(v=VS.80).aspx

    我建议你先启动新端口的监听线程,然后再终止监听旧端口的线程。因为跟据线程的特性,终止的过程可能需要一定时间。

    简单的方式是,自动重新启动你的程序,然后读取新的端口值监听。

    我想用一个重启按钮来实现,使端口可以反复修改,修改一次点重启就会监听新的端口。这样“旧的”监听线程实际上是上一次重启的“新”监听线程。怎么让一个按钮能够准确结束上一个监听线程?(重启按钮自己建立新线程,还要自己结束自己上一次建立的线程,能实现么?)

    重新启动程序怎么做?因为我在程序中设置了默认的port,重新启动程序port不就变成默认值了么?

    2013年1月31日 2:21
  • 我们以这篇文章中的代码来说明:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.tcplistener(v=VS.80).aspx

    你点击重启后,先需要停止旧的监听端口,那么你需要在代码中的两个 while 循环中都设置标志来判断是否需要继续读取数据,你可以使用一个全局的变量,也可以使用EVENT_HANDLE来控制,通过WaitFor来控制两个 while 循环是执行还是终端,只所以在停止线程前需要先终止线程执行体的方法,是因为线程除了由进程控制生命周期外,就完全依赖它所执行的方法体了。当两个 while 结束后,你就需要执行 server.Stop() 来停止监听。一个简便的方式是当两个 while 被要求中断时抛出异常,那么线程就会立即终止,同时 finanly 中的代码保证 server.Stop() 总是会被调用。

    线程一旦终止后是无法再重新启动的,你需要新建一个线程来启动你新端口的监听。


    重启整个进程(或者可以用卸载应用程序域来实现)前,先把新端口写入磁盘,或者作为启动参数,启动的进程通过磁盘或者启动参数来读入新的端口值。
    • 已编辑 Skyseer 2013年1月31日 2:46
    • 已标记为答案 Mclovin 2013年1月31日 3:37
    2013年1月31日 2:35
  • 我们以这篇文章中的代码来说明:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.tcplistener(v=VS.80).aspx

    你点击重启后,先需要停止旧的监听端口,那么你需要在代码中的两个 while 循环中都设置标志来判断是否需要继续读取数据,你可以使用一个全局的变量,也可以使用EVENT_HANDLE来控制,通过WaitFor来控制两个 while 循环是执行还是终端,只所以在停止线程前需要先终止线程执行体的方法,是因为线程除了由进程控制生命周期外,就完全依赖它所执行的方法体了。当两个 while 结束后,你就需要执行 server.Stop() 来停止监听。一个简便的方式是当两个 while 被要求中断时抛出异常,那么线程就会立即终止,同时 finanly 中的代码保证 server.Stop() 总是会被调用。

    线程一旦终止后是无法再重新启动的,你需要新建一个线程来启动你新端口的监听。

    实在是不好意思,研究半天虽然大概明白了是要怎么实现,但是落实到代码上还是很迷糊不知道怎么写,能帮忙把代码写下么?

    中断抛出异常,event_handle我都不懂怎么做……

    我用全局变量试了下:

    bool isstop;

    在while循环前赋值:isstop = false;

    在while循环里面是:

    if(isstop) break;

    重启按钮:

    isstop = true;

    Thread newlisten = new Thread(new ThreadStart(StartListening));

    newlisten.Start();

    • 已编辑 Mclovin 2013年1月31日 3:28
    2013年1月31日 3:17