2016-04-27 22 views
0

java docは書かなければならないと言いました。以前のwirteでは動作しませんでした。どのようにjava7 nioソケットWritePendingExceptionを解決するには?

非同期ソケットチャネルへの書き込みを試みて、前回の書き込みが完了しなかった場合にチェックされない例外がスローされます。

この段階を説明するための簡単なコード:

val writeLock = new ReentrantLock 

def sendMsg(data: ByteBuffer) = { 
    val p = Promise[Unit] 

    writeLock.lock() 

    socketChannel.write(data, 1, new CompletionHandler[Integer, Int] { 
    override def completed(result: Integer, attachment: Int): Unit = { 
     writeLock.unlock() 

     p.trySuccess(Unit) 
    } 

    override def failed(exc: Throwable, attachment: Int): Unit = { 
     p.tryFailure(exc) 
     writeLock.unlock() 
    } 
    }) 
    p.future 
} 

が、それはIllegalMonitorStateException例外をスロー:

sendMsg(data: ByteBuffer): Future[Unit] = { 
    val p = Promise[Unit] 
    this.synchronized { 
     //socketChannel: AsynchronousSocketChannel is connected socket 
     socketChannel.write(data, 1, new CompletionHandler[Integer, Int] { 
     override def completed(result: Integer, attachment: Int): Unit = { 
      p.trySuccess(Unit) 
     } 

     override def failed(exc: Throwable, attachment: Int): Unit = { 
      p.tryFailure(exc) 
     } 
     } 
    } 
    p.future 
    } 

私はそれがこのunworkコードで完了するまでwrite操作をロックしようとします。
これを同時に実行するにはいくつかの助けが必要です。 さらに、私は別の質問があります。それはjava.sdkとは関係ありません。非同期操作が完了するのを待つ必要があるようです。ありがとう

答えて

0

Javaはこれを処理する必要はありません。コード。

「待つ」必要はありません。あなたはあなたのデータを書いて、書くためにクライアントを「無効にする」。書き込みが完了すると(そのような方法があるため)、クライアントの書き込みを再検証します。

重要な概念は、書き込むチャネルを選択するときに、その時点で「無効」であるチャネルをスキップすることです。

私は数年前にNIOの非同期IOの実装を作った、あなたはさらにヒント

https://github.com/NadirRoGue/asyncnetworkengine/tree/master/src/org/mmocore/network

がMMOConnection.startWriteTask `で MMOClient.sendPacket() WriteHandler.completed()

+0

で特異的に見てみましょう得るために見てかかることがあります'ここでは、スレッドプールで' write'メソッドを使用します。しかし、現在のスレッドをロックするだけの 'MMOConnection.executeWriteTask'メソッドは' startWriteTask'メソッドを囲んでいます。 'writeWriteTask'が' write'が保留中のときに実行できないようにする方法はありますか? – LoranceChen

+0

@ LoranceChenだから、保留中に実行するのを避けるために、私は '_pendingWrite'フラグを持っています。もう一つのアプローチは 'completed'メソッドが' sendQueue'がパケットを持っている間に次の書き込みをトリガすることです。これが一旦空になると、書き込みタスクはトリガされなくなるので、writeタスク – Nadir

+0

をトリガするために 'sendPacket'(別のフラグを付けて、最後は同じ)を使用する必要があります。 libを使用しますか? '_core.executeWriteTask'がすぐに戻るため、' _pendingWrite'はまったく影響しないと思います。 – LoranceChen

関連する問題