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が言ったように、受信タイムアウトを設定して、永遠にreceive()を試みてそこに座っていないようにする必要があります。

new Thread(listenerRunnable)また、 stopListening()メソッドがスレッドの終了を待機できるように、によって返されるThreadオブジェクトを保持します。

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

receiveを呼び出す前に、setSoTimeout(timeout)を追加する必要があります。これにより、SocketTimeoutExceptionsが定期的にスローされますが、Datagramソケットは開いたままになります。これにより、ループ変数を定期的にチェックできます。

さらに、ループを最初の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 に答える