两台完全不同的计算机,其中一台运行Windows 7 Ultimate和一台运行Windows Server,它们运行相同的程序。该程序使用GSocket在它们之间建立P2P网络体系结构,这表明底层套接字类型是特定于平台的,因此是窗口SOCKET
。
类似于select()
的函数用作检测输入队列中是否有数据的一种形式,它可以完美地工作。 Windows 7客户端强制断开连接时,什么也没有发生,类似于select()
的函数超时,这是预期的行为(因为它只能返回取消或超时错误,并且返回TRUE
/ FALSE
值)
但是,如果Windows服务器对等方以相同的方式断开连接,则会导致类似select()
的函数返回输入队列中存在数据,这反过来又调用recv()
,该失败会失败。 (-1)
。在这种情况下,g_socket_get_available_bytes(socket)
将返回0
,因为没有字节,这说明recv()
失败。
现在这不是客户端/服务器之间的问题,因为如果我交换计算机以使另一台计算机成为连接的计算机,则会发生相同的情况。 而且我不知道当两台计算机都是Windows并且都运行相同的GTK +版本运行时时,这是特定于平台的问题。
是什么原因导致这种严重的不良行为?
在Windows发行版中,类似select()
的函数行为(g_socket_condition_timed_wait()
)是否有很大差异。
基本上,此问题已通过替换解决
g_socket_condition_timed_wait(socket, G_IO_IN, 32 * MS_SECOND, NULL, NULL);
与
gboolean cnp_receive_wait_for_available_bytes (GSocket* socket/*, gint64 timeout*/)
{
return (g_socket_get_available_bytes(socket) > 0);
}
在这种情况下,如果在强行断开连接时未通过检查,但老实说,我更喜欢另一种方式,如果强行断开连接,g_socket_condition_timed_wait
返回TRUE
并导致{{1} }失败,因此我无需执行任何其他类型的ping操作即可检测到对等方已强制断开连接。
更新这不是recv
的错,我才发现
g_socket_condition_timed_wait()
类似于gboolean cnp_send_failed (GSocket* socket)
{ /* Probably unspecified how recv() and send() tolerates a zero-length message. */
return(g_socket_send_with_blocking(socket, "", 0, TRUE, NULL, NULL) == (-1));
}
的操作仅在Windows Server对等方断开连接时才对Windows 7计算机失败,这只会使问题更严重,因为它使我无法检测到Windows Server计算机通过上述功能强行断开连接。我不知道OS是否能正确处理关闭输入/输出通道。