2

我正在尝试创建一个将在单独的线程上侦听的 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.bind(未知来源)的 java.net.PlainDatagramSocketImpl.bind0(本机方法)处绑定

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

谢谢

4

2 回答 2

2

正如 Peter Tillemans 所说,你应该设置一个接收超时,这样你就不会坐在那里试图永远接收()。

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

public void stopListening() {
    keepListening = false;
    listenerThread.join();
}
于 2010-06-25T22:13:15.670 回答
1

您必须在调用接收之前添加一个 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();
        }
于 2010-06-25T21:41:46.340 回答