简体   繁体   English

如何解决java7 nio socket WritePendingException?

[英]how to solve java7 nio socket WritePendingException?

java doc said it will occurred when do write operate by former wirte not complete. java doc表示,当由原作者完成写操作时,会发生这种情况。

Unchecked exception thrown when an attempt is made to write to an asynchronous socket channel and a previous write has not completed. 尝试写入异步套接字通道并且先前的写入未完成时,引发未经检查的异常。

a simple code to describe this stage: 一个简单的代码来描述这个阶段:

  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
  }

I attempt to lock write operation until it completed with this unwork code: 我尝试锁定write操作,直到使用以下无效代码完成操作:

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
}

but it throw IllegalMonitorStateException exception. 但是会抛出IllegalMonitorStateException异常。
Hope some help to to run it concurrently. 希望能有所帮助来同时运行它。 Besides, I have another question, why not java sdk deal with it.It seems I should wait a async operation complete.Thanks 此外,我还有一个问题,为什么不使用Java sdk处理它呢?似乎我应该等待异步操作完成。

Is not that Java should handle this, because if it would you would be loosing control over your code. Java是否应该处理此问题,因为如果这样做,您将失去对代码的控制。

You don't have to "wait". 您不必“等待”。 You write your data, and "invalidate" the client for writing. 您写入数据,并使客户端“无效”以进行写入。 When the write is completed (that's why you have such method), you re-validate the client for writting. 写入完成后(这就是您使用这种方法的原因),您将重新验证客户端以进行写入。

The key concept is that, when selecting channels to write, you skip those that are "invalid" at that momment. 关键概念是,在选择要写入的通道时,您会跳过那些在那一刻“无效”的通道。

I made a nio async io implementation few years ago, you might take a look to get further hints 几年前,我实现了nio async io的实现,您可以看看以获取更多提示

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

Take a look specifically at MMOClient.sendPacket() WriteHandler.completed() 看一下MMOClient.sendPacket() WriteHandler.completed()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM