2016-11-21 3 views
0

Für Lernzwecke implementiere ich UDP mit den Mechanismen von TCP (so dass es eine sichere Übertragung garantiert).Stuck in Interation, die durch ein Semaphor geschützt ist

Die Semaphore bin ich binär, so ist es sem = new Semaphore(1);. Ich benutze diesen Semaphor, um den Eingang für meine sendBuf zu steuern, die eine List enthält, die alle Pakete enthält, die gesendet, aber noch nicht bestätigt wurden. Da ich manchmal Pakete lösche, wenn ich eine ACK bekomme, muss ich sicherstellen, dass ich nicht mit einem Thread iteriere, während ein anderer Thread etwas daraus löscht.

Die Sache, die mich wirklich nervt, ist dies:

public void timeoutTask(long seqNum) { 
    System.out.println("Timeout for package with SeqNum " + seqNum 
      + " happened."); 
    timeoutValue *= 2; 
    try { 
     System.out.println("Acquire? in timeouttask"); 
     sem.acquire(); 
     System.out.println("Acquired! in timeouttask"); 
    } catch (InterruptedException e1) { 
     System.out.println("semaphore not acquired"); 
     e1.printStackTrace(); 
    }for (FCpacket packet : sendBuf) { 

     System.out.println("Iterating!"); 
     if (packet.getSeqNum() == seqNum) { 
      System.out.println("Package for seqNum " + seqNum + " found!"); 
      reSendData = packet.getSeqNumBytesAndData(); 
      DatagramPacket reSendPacket = new DatagramPacket(reSendData, 
        reSendData.length, hostaddress, SERVER_PORT); 

      try { 
       clientSocket.send(reSendPacket); 
       System.out.println("Packet with seq " + seqNum 
         + " send again"); 
       packet.setTimestamp(0); 
       startTimer(packet); 
       new ReceiveHandler(reSendData, reSendData.length, 
         clientSocket, rcvData, UDP_PACKET_SIZE, this).run(); 
      } catch (IOException e) { 
       System.out.println("Couldn't send package"); 
       e.printStackTrace(); 
      } 
     } 
    } 
    sem.release(); 
    System.out.println("released! in timeouttask"); 

Konsolenausgabe mir folgendes ergibt:

Acquire? in timeouttask 

Acquired! in timeouttask 

Iterating! 

Paket for seqNum 1 found! 

Packet with seq 1 send again 

So ist es die Semaphore wird, beginnt Iterieren, sendet sie sogar das Paket, So, jetzt sollte es entweder: Iterate erneut ("iterating!") ODER den Semaphor freigeben. Keine der oben genannten passiert, es ist einfach fest. Ich habe keine Ahnung warum - irgendwelche Ideen?

+0

Was meinst du mit „Ich UDP mit den Mechanismen der TCP bin der Umsetzung“ ?? – SZD

+0

genau das, was ich in den Klammern gesagt habe. UDP garantiert nicht, dass die Pakete am Ziel ankommen, TCP prüft, ob sie es tun, und sendet sie nicht erneut. – InDaPond

+0

Es scheint, dass Thread in run() -Methode für eingehende Pakete wainting – Javoslaw

Antwort

1

Wenn ReceiveHandler ein Thread ist, sollte es als

new ReceiveHandler(reSendData, reSendData.length, clientSocket, rcvData, UDP_PACKET_SIZE, this).start(); 

geltend gemacht werden, aber wenn es ein Runnable ist, sollte es als geltend gemacht werden

new Thread(new ReceiveHandler(reSendData, reSendData.length, clientSocket, rcvData, UDP_PACKET_SIZE, this)).start(); 

run() wird die Aufgabe in einem separaten nicht ausführen Faden.

sehen: What's the difference between Thread start() and Runnable run()

Verwandte Themen