2016-09-12 9 views
0

を使用して3つのパケットのうち2つのみが送信されていますので、AsynchronousSocketChannelクラスに基づいて小さなクライアント< - >サーバー通信アプリケーションを構築しています。 私はすべてがうまく動作するように管理しました。サーバが稼働していて、クライアントが接続でき、パケットがすべて送受信されています。 少なくともパケットの束を次々と送ろうとするまで(少なくとも3パケットと言います)、少し前に検索した後に修正することができたWritePendingExceptionに向かって走りますが、パケットはまだ送信されていません正しく。 私のデバッグから、サーバが3パケットを送信しようとしたようですが、すべて3を送信しましたが、クライアントは最初の2つだけを受信しますが、問題がどこにあるのか分かりません。非同期ソケット

パケットを作成し、彼らがそうのよう_sendQueueに追加されています:

_sendQueue.add(packet); 

_sendQueueがたByteBufferのConcurrentLinkedQueue(私のパケットである)である私はちょうど尋ねる助けるために必要。 その後、パケットは次のような方法で送信されている:すべてのパケットが書き込まれた後

public final void executeWriteTask() 
{ 
    if (!_sendQueue.isEmpty()) 
    { 
     _writeLock.lock(); 
     if (!_pendingWrite) 
     { 
      _pendingWrite = true; 

      ThreadPool.execute(() -> 
      { 
       final PacketWriter packet = _sendQueue.poll(); 
       final ByteBuffer duplicate = packet.getBuffer().duplicate(); 
       System.out.println("Sending packet opcode: " + duplicate.getInt()); 
       _channel.write(packet.getBuffer(), this, _writeHandler); 
      }); 
     } 
     _writeLock.unlock(); 
    } 
} 

、この方法は非常に基本的にすべての3が送信されている、これはどのような私のprintlnで、キュー内の次のパケットのために再び呼び出されています結構です

Sending packet opcode: 0 
Sending packet opcode: 1 
Sending packet opcode: 1 

が、クライアント上:ショー

Received packet opcode: 0 
Received packet opcode: 1 

私は3秒後に再度手動で読み込む呼び出ししようとしているような、多くのことを試みたが、 3秒後にサーバーから3番目のパケットを送信しようとしましたが、それはうまくいきませんでしたが、それは私が望むものではありません。実際に問題が実際に試したものかどうかを確認することでした瞬時に3つのパケットを送信すると、それがわかった。 3パケットはどこに行きましたか?私はこれ以上深くデバッグする方法は考えられません。どんな助けもありがたいです。

注記自分でビルドしたいので、あらかじめ作成された通信コードを教えてください。

+0

パケットは常にネットワーク上で失われます。典型的には非常に小さいバッファが満たされると、パケットがドロップされます。そのため、TCPは信頼性の高い通信を実現するために作られました。 –

+0

申し訳ありませんが、私の通信はTCPに基づいていると確信しています。javaのAsynchronousSocketChannelに基づいて、 –

+0

TCPはセグメント配信を保証し、欠落セグメントを再送信するよう要求します。あなたはTCPですべてを得るでしょう。 –

答えて

0

まあ、私の質問に直接答えませんが、それは問題を解決するようです。 私が推測するには、パケットの洪水をかそこら防ぐ何らかのメカニズムですので、私が代わりにパケットを次々に送るので、彼らは1つのパケットにバッチ処理された後、そのように、全体として送信されることが決定:

public final void executeWriteTask() 
{ 
    if (!_sendQueue.isEmpty()) 
    { 
     _writeLock.lock(); 
     if (!_pendingWrite) 
     { 
      _pendingWrite = true; 

      ThreadPool.execute(() -> 
      { 
       final Queue<PacketWriter> copy = new ConcurrentLinkedQueue<>(); 
       while (!_sendQueue.isEmpty()) 
        copy.add(_sendQueue.poll()); 

       int bytes = 0; 
       for (final PacketWriter packet : copy) 
        bytes += packet.getBuffer().limit(); 
       final ByteBuffer toSend = ByteBuffer.allocateDirect(bytes); 
       for (final PacketWriter packet : copy) 
        toSend.put(packet.getBuffer()); 
       toSend.flip(); 

       _channel.write(toSend, this, _writeHandler); 
      }); 
     } 
     _writeLock.unlock(); 
    } 
} 

その後、クライアント:

関連する問題