【问题标题】:Socket not closing properly插座未正确关闭
【发布时间】:2011-03-08 11:40:35
【问题描述】:

我正在尝试创建一个侦听单独线程的 UDP 侦听器。它第一次工作正常,但是当我停止连接然后重新启动时,它给了我错误。

listenerRunnable = new Runnable() {
        public void run() {
            //This thread will listen keep listening to the UDP traffic and put it to the log source string
            try {
                sock = new DatagramSocket(portNumber);
            } catch (SocketException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while(keepListening) {
                try {
                    pack = new DatagramPacket(recievedData, BUFFERSIZE);
                    sock.receive(pack);

                    String data = new String(pack.getData(), 0, pack.getLength());
                    addToLog(data);
                    System.out.println(data);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                sock.close();
            }
        }
    };

/**
 * Function to start the listening thread.
 */
public void startListening(int portNum) {
    keepListening = true;
    portNumber = portNum;

    listenerThread = new Thread(listenerRunnable);

    logSource_buffer = "";
    logSourcehtml_buffer = "";
    logSourcehtml_temp = "";
    ipListIndex_beg = 0;
    ipListIndex_end = -1;

    if(!listenerThread.isAlive()) {
        listenerThread.start();
    }
}

/**
 * stops the listening thead.  When the listening thread sees that keepListening is set to false
 * it will reach the end of its loop, close the socket, and the thread will die.
 */
public void stopListening() {
    keepListening = false;
}

它给了我以下错误:

logUpdatingThread 已进入同步块!!! java.net.SocketException:无法识别的 Windows 套接字错误:0:无法绑定 在 java.net.PlainDatagramSocketImpl.bind0(本机方法) 在 java.net.PlainDatagramSocketImpl.bind(Unknown Source)

指向 sock.recieve(pack); 的行 似乎由于某种原因套接字没有关闭,因为我认为它在 sock.recieve(pack) 等待并且永远不会退出 while 循环来关闭套接字。不过,我该如何解决呢?

谢谢

【问题讨论】:

    标签: java sockets udp datagram


    【解决方案1】:

    正如 Peter Tillemans 所说,您应该设置接收超时,这样您就不会一直坐在那里尝试接收()。

    另外,保留new Thread(listenerRunnable) 返回的 Thread 对象,以便您的 stopListening() 方法可以等待线程终止:

    public void stopListening() {
        keepListening = false;
        listenerThread.join();
    }
    

    【讨论】:

      【解决方案2】:

      您必须在调用接收之前添加一个 setSoTimeout(timeout)。这将定期抛出 SocketTimeoutExceptions,但保持数据报套接字打开。这将允许您定期检查循环变量。

      此外,您应该将循环移动到第一个 try-catch 块中,并添加一个 finally 块来关闭套接字。

      喜欢:

              try {
                  sock = new DatagramSocket(portNumber);
                  sock.setSoTimeout(250);
                  while(keepListening) {
                      try {
                          pack = new DatagramPacket(recievedData, BUFFERSIZE);
                          sock.receive(pack);
      
                          String data = new String(pack.getData(), 0, pack.getLength());
                          addToLog(data);
                          System.out.println(data);
                      } catch (IOException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                  }
              } catch (SocketException e1) {
                  // TODO Auto-generated catch block
                  e1.printStackTrace();
              } finally {
                  sock.close();
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        • 1970-01-01
        • 2011-11-03
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多