2016-11-21 7 views
0

学習の目的で、私はTCPのメカニズムを使ってUDPを実装しています(安全な転送を保証するため)。セマフォーで保護されたInterationでスタックされています

Semaphore私はバイナリですので、sem = new Semaphore(1);です。 このセマフォを使用して、sendBufの入り口を制御します。これは、送信されたがまだ確認されていないすべてのパッケージを含むListです。私はACKを受け取ったときにパッケージを削除することがあるので、別のスレッドが何かを削除している間に、あるスレッドでは反復していないことを確認する必要があります。

本当に私を悩ませているものはこれです:

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

コンソール出力は私に次のようになります:

Acquire? in timeouttask 

Acquired! in timeouttask 

Iterating! 

Paket for seqNum 1 found! 

Packet with seq 1 send again 

だから、セマフォを取得し、繰り返し処理を開始し、それもパッケージを送信し、今度は、次のいずれかを行う必要があります。再度反復する(「反復する」)か、セマフォを解放する。上記のいずれも起こらず、ちょうど立ち往生しています。なぜ私は考えていません - どのようなアイデアですか?

+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()

関連する問題