【发布时间】:2015-12-06 02:05:37
【问题描述】:
当我在阻塞模式下使用套接字时,我可以有一个简单的系统来做这样的事情:
client server
A -------------------> B
register
A <------------------> B
(various messages)
A -------------------> B
unregister
发送unregister消息后,进程A可以立即退出,而B按预期收到消息。
如果我在 A 的套接字上打开非阻塞模式,B 永远不会收到 unregister 如果 A 发送该消息然后立即退出(我通过在发送 unregister 后添加 sleep(1) 进行测试,在这种情况下它可以工作正如预期的那样。)因此,或多或少,我的客户无法彻底取消注册。
注意:当 B poll() A 的套接字时,我收到一个挂断信号 (POLLHUP) 而不是最后一个 unregister 消息,然后挂断。
我尝试添加一个调用以重新打开阻塞模式,但不知何故它没有任何区别。我使用下面的代码来改变阻塞模式:
int optval(0 or 1);
ioctl(get_socket(), FIONBIO, &optval);
以防万一,我也尝试使用fcntl(),尽管我确信就内核而言它会调整相同的标志。
int flags(fcntl(get_socket(), F_GETFL));
flags |= O_NONBLOCK; // use this line to turn ON
flags &= ~O_NONBLOCK; // use this line to turn OFF
fcntl(get_socket(), F_SETFL, flags);
附带说明,我使用 read() 和 write() 函数发送和接收消息。
更新:
对于那些感兴趣的人,测试现在在我们的 git 中:
服务器:https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/tests/test_shutdown_server.cpp
客户:https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/tests/test_shutdown_client.cpp
这些使用 snap 库,主要是依赖于 tcp 客户端/服务器的 snap_communicator:
tcp:https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/lib/tcp_client_server.cpp
通讯员:https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/lib/snap_communicator.cpp
【问题讨论】:
标签: c linux sockets nonblocking