2016-11-21 5 views
0

학습 목적으로 안전한 전송을 보장하기 위해 TCP의 메커니즘을 사용하여 UDP를 구현하고 있습니다.세마포어로 보호되는 Interation에 갇혀있다

Semaphore 내가 사용하는 이진 값이므로 sem = new Semaphore(1);입니다. 나는이 세마포어를 사용하여 sendBuf에 대한 입구를 제어하는데, 이것은 에 보내졌지만 아직 확인되지 않은 모든 패키지를 포함합니다. ACK를 받으면 때로는 패키지를 제거하기 때문에 다른 스레드가 뭔가를 삭제하는 동안 한 스레드로 반복하지 않는지 확인해야합니다. , 심지어 패키지를 전송, 반복 시작,

Acquire? in timeouttask 

Acquired! in timeouttask 

Iterating! 

Paket for seqNum 1 found! 

Packet with seq 1 send again 

그래서는 세마포어를 가져옵니다

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"); 

콘솔 출력은 다음 날 제공 :

정말 날 귀찮게되는 일이있다 이제는 다음과 같이해야합니다 : 다시 반복 ("iterating!")하거나 세마포어를 해제하십시오. 위의 어떤 것도 발생하지 않고 방금 막혔습니다. 나는 이유를 모른다 - 어떤 아이디어?

+0

"TCP의 메커니즘으로 UDP를 구현하고 있습니까?" – SZD

+0

내가 괄호 안에 말한 것. UDP는 패킷이 목적지에 도달하는 것을 보장하지 않으며, TCP는 패킷을 확인하고 그렇지 않으면 다시 전송합니다. – InDaPond

+0

들어오는 패킷에 대해 스레드가 run() 메서드에서 wainting 인 것 같습니다. – Javoslaw

답변

1

ReceiveHandlerThread 경우, 그것은

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

로 호출해야하지만이 Runnable 경우, 그것은

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

run() 별도의 작업을 실행하지 않습니다

로 호출되어야한다 실.

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