2010-06-25 9 views
2

Je suis en train de créer un écouteur UDP qui écoutera sur un fil séparé. Cela fonctionne bien la première fois mais quand j'arrête la connexion et la redémarre, cela me donne des erreurs.Socket ne se ferme pas correctement

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; 
} 

Il me donne l'erreur suivante:

logUpdatingThread has entered synchronized block!!! java.net.SocketException: Unrecognized Windows Sockets error: 0: Cannot bind at java.net.PlainDatagramSocketImpl.bind0(Native Method) at java.net.PlainDatagramSocketImpl.bind(Unknown Source)

qui pointe vers la ligne avec sock.recieve (pack); Il semble que pour une raison quelconque, le socket ne se ferme pas parce que, je pense, il attend à sock.recieve (pack) et ne sort jamais de la boucle while pour fermer le socket. Comment pourrais-je contourner cela?

Merci

Répondre

1

Vous devez ajouter un setSoTimeout (délai d'attente) avant d'appeler recevoir. Cela lancera régulièrement SocketTimeoutExceptions, mais en gardant le socket Datagram ouvert. Cela vous permettra de vérifier régulièrement la variable de boucle.

De plus, vous devez déplacer la boucle à l'intérieur du premier bloc try-catch et ajouter un bloc finally pour fermer le socket.

aime:

 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(); 
     } 
2

Comme le dit Peter Tillemans, vous devez définir un délai de réception afin que vous n'êtes pas assis là à essayer de recevoir() pour toujours.

En outre, garder la main sur l'objet de discussion retourné par new Thread(listenerRunnable) afin que votre méthode stopListening() peut attendre le fil à mourir:

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