Гнездо не закрывается должным образом - PullRequest
2 голосов
/ 26 июня 2010

Я пытаюсь создать прослушиватель 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 Sockets: 0: Невозможно выполнить привязку на java.net.PlainDatagramSocketImpl.bind0 (собственный метод) на java.net.PlainDatagramSocketImpl.bind (неизвестный источник)

, какие точкина линию с sock.recieve (пачкой);По какой-то причине сокет не закрывается, потому что, я думаю, он ожидает в sock.recieve (pack) и никогда не выходит из цикла while для закрытия сокета.Как бы мне обойти это, хотя?

Спасибо

Ответы [ 2 ]

2 голосов
/ 26 июня 2010

Как сказал Питер Тиллеманс, вы должны установить тайм-аут приема так, чтобы вы не сидели и не пытались навсегда получить ().

Кроме того, удерживайте объект Thread, возвращенный new Thread(listenerRunnable)что ваш метод stopListening () может дождаться смерти потока:

public void stopListening() {
    keepListening = false;
    listenerThread.join();
}
1 голос
/ 26 июня 2010

Вам нужно будет добавить setSoTimeout (тайм-аут) перед вызовом приема. Это будет регулярно генерировать исключения SocketTimeoutException, но при этом сокет дейтаграммы будет открыт. Это позволит вам регулярно проверять переменную цикла.

Кроме того, вы должны переместить цикл внутри первого блока 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();
        }
...