简体   繁体   English

NIO:发送消息然后立即断开连接

[英]NIO: Send message and then disconnect immediately

In some circumstances I wish to send an error message from a server to client using non-blocking I/O ( SocketChannel.write(ByteBuffer) ) and then disconnect the client. 在某些情况下,我希望使用非阻塞I / O( SocketChannel.write(ByteBuffer) )从服务器向客户端发送错误消息,然后断开客户端连接。 Assuming I write the full contents of the message and then immediately disconnect I presume the client may not receive this message as I'm guessing that the OS hasn't actually sent the data at this point. 假设我写了消息的全部内容然后立即断开我假设客户端可能没有收到此消息,因为我猜测操作系统此时并未实际发送数据。

Is this correct, and if so is there a recommended approach to dealing with this situation? 这是否正确,如果是这样,是否有建议的方法来处理这种情况?

I was thinking of using a timer whereby if I wish to disconnect a client I send a message and then close their connection after 1-2 seconds. 我正在考虑使用计时器,如果我想断开客户端,我会发送一条消息,然后在1-2秒后关闭它们的连接。

SocketChannel.write will in non-blocking mode return the number of bytes which could immediately be sent to the network without blocking. SocketChannel.write将以非阻塞模式返回可以立即发送到网络而不会阻塞的字节数。 Your question makes me think that you expect the write method to consume the entire buffer and try asynchronously to send additional data to the network, but that is not how it's working. 您的问题让我认为您希望write方法使用整个缓冲区并异步尝试将其他数据发送到网络,但这不是它的工作方式。

If you really need to make sure that the error message is sent to the client before disconnecting the socket, I would simply enable blocking before calling the write method. 如果确实需要确保在断开套接字之前将错误消息发送到客户端,我只需在调用write方法之前启用阻塞。 Using non-blocking mode, you would have to call write in a loop, counting the number of bytes being sent by each invocation and exit the loop when you've succeeded to pass the entire message to the socket (bad solution, I know, unnecessary code, busy wait and so on). 使用非阻塞模式,你必须在循环中调用write,计算每次调用发送的字节数,并在成功将整个消息传递给套接字时退出循环(糟糕的解决方案,我知道,不必要的代码,忙等待等等)。

you may be better off launching a thread and synchronously write data to the channel. 你可能最好启动一个线程并同步地将数据写入通道。 the async api is more geared toward "one thread dispatching multiple channels" and not really intended for fire and forget communications. async api更倾向于“一个线程调度多个通道”而不是真正用于消防和忘记通信。

The close() method of sockets makes sure, everything sent using write before is actually sent before the socket is really closed. 套接字的close()方法确保,使用write之前发送的所有内容实际上是在套接字真正关闭之前发送的。 However this assumes that your write() was able to copy all data to the tcp stacks output window, which will not always work. 但是,这假设您的write()能够将所有数据复制到tcp堆栈输出窗口,这不会始终有效。 For solutions to this see the other answers. 对于解决方案,请参阅其他答案。

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

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