监听程序我放在一个线程里面,我要实现开始监听和停止监听。
现在的情况是停止监听后必须得改端口号,不能用上次的端口号,否则出现报错(通常每个套接字地址(协议/网络地址/端口)只允许使用一次!!)。
可是我停止监听时把线程都停止了啊,怎么才能释放那个端口啊??!!
最好能用方法实现void StopPort(int portnum){......;}
求解答。谢谢各位!

解决方案 »

  1.   

    ls所说的方法不适用啊,我希望是在主进程中释放端口,以
    void StopPort(int portnum){......;}这种方式实现。
      

  2.   

    在主线程设置一个变量needStop来停止监听线程,把needStop设为true,他就停止了。void ListeningThreadMethod()
    {
    //启动
    ...
    while(!needStop)
    {
    //监听
    }
    //停止,清理
    }
      

  3.   

     我目前用的方法类似于LS的这种方法,
    public void Listen(object port_num)//监听某个端口
            {
                int port = (int)port_num;            /**/
                ///创建终结点(EndPoint)
                // IPAddress ip = IPAddress.Parse(host);//把ip地址字符串转换为IPAddress类型的实例
                IPEndPoint ipe = new IPEndPoint(0, port);//用指定的端口和ip初始化IPEndPoint类的新实例            /**/
                ///创建socket并开始监听
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket对像,如果用udp协议
                s.Bind(ipe);//绑定EndPoint对像(2000端口和ip地址)
                s.Listen(0);//开始监听
                while (flag)
                {            ///接受到client连接,为此连接建立新的socket,并接受信息
                    Socket temp = s.Accept();//为新建连接创建新的socket
                    SetState("已连接");
                    byte[] recvBytes = new byte[1024];
                    int bytes;
                    bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
                    string str = "";
                    str= Encoding.ASCII.GetString(recvBytes, 0, bytes);
                    SetRealTimeValuePM10(str);
                    
                    /**/
                    ///给client端返回信息
                    string sendStr = "ok!Client send message successful!";
                    byte[] bs = Encoding.ASCII.GetBytes(sendStr);
                    temp.Send(bs, bs.Length, 0);//返回信息给客户端
                    temp.Close();
                }
                //s.close();
            }
    //上面这个方法放到子线程执行的。在主线程的button事件中修改flag的值,打断,根本跳不到下面执行s.close();
    也就是说可能我的主线程中修改flag,影响不了在执行的子线程中的flag值。
    不知道如何是好,因为之前搜索CSDN上面的帖子又有说close无法释放端口的。
    void StopPort(int portnum){......;}这种方式能实现吗?
    请有经验的大神解答一下!
      

  4.   

    把你的 socket s 做为一个静态变量。
    在另一个button事件中close掉就行了。
    监听中是阻塞的不能响应你的while(flag)
      

  5.   

    谢谢你的回答,可是socket不能定义成静态变量啊!
      

  6.   

    这个while已经死循环了,还能响应其他处理吗?
      

  7.   

    将监听的socket对象,定义为类成员1、开线程进程监听,若有用户连进来,则再开线程进行通讯,同时将此连接的用户加入一个维护列表。
    2、每一个连进来的用户,都新开的一个线程进行处理。同时也可以再开一个线程用来操控用户列表。
    3、所有用户都退出则监听关闭,或其他条件满足的时候,逐一断开每一个用户,最后关闭监听此开子线程的方式,仅仅适合连接数不太大的场合。几千个用户就不能采用这种方式。
      

  8.   

    class 你的类名
    {
       Socket s;    //  将你的socket放到这里来定义
       btn_Click()
       {
         try
         {
           s.close()    //  关闭监听放在这里
         }
       }
       
      public void Listen(object port_num)   // 你的监听线程
       {
          ...
         while(true)
         {
           try
             {
                //  你的处理
             }
           catch
             {
               break;    //  关闭端口后,退出你的监听线程,注意,你可能会收到null内容,也需要手工退出
              }
          }
       }
    }你可以试一下!
      

  9.   

    你对同步异步的理解我觉得还是不恰当吧
    Socket通信方式:1,同步:客户端在发送请求之后必须等到服务器回应之后才可以发送下一条请求。串行运行2,异步:客户端请求之后,不必等到服务器回应之后就可以发送下一条请求。并行运行