Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是";“读取零字节”;从套接字监视POSIX C中TCP/IP断开连接的有效方法?_C_Linux_Sockets_Tcp_Posix - Fatal编程技术网

是";“读取零字节”;从套接字监视POSIX C中TCP/IP断开连接的有效方法?

是";“读取零字节”;从套接字监视POSIX C中TCP/IP断开连接的有效方法?,c,linux,sockets,tcp,posix,C,Linux,Sockets,Tcp,Posix,我目前正在审查一个实现POSIX套接字的C应用程序。此应用程序通过从套接字读取零字节,间歇性地检查与服务器的连接是否有效。然后检查是否设置了errno以确定连接是否正常。这是一个稳健的解决方案吗 uint32_t IsConnected() { char dummy[10]; if(read(global_sockfd, dummy, 0) == -1) { if(errno != EWOULDBLOCK &&

我目前正在审查一个实现POSIX套接字的C应用程序。此应用程序通过从套接字读取零字节,间歇性地检查与服务器的连接是否有效。然后检查是否设置了errno以确定连接是否正常。这是一个稳健的解决方案吗

uint32_t IsConnected()
{
        char dummy[10];
        if(read(global_sockfd, dummy, 0) == -1)
        {
            if(errno != EWOULDBLOCK && errno != EAGAIN)
                return FALSE;
            else
                return TRUE;
        }   
        else
            return TRUE;
}
对。返回值部分对此进行了说明:

这些调用返回接收的字节数,如果 发生错误。发生错误时,errno设置为 指出错误

当流套接字对等方执行有序关闭时 返回值将为0(传统的“文件结束”返回)

不同域(如UNIX和Internet)中的数据报套接字 域)允许零长度数据报。当这样的数据报 接收时,返回值为0

如果请求的字节数不正确,也可能返回值0 从流套接字接收的值为0

TCP套接字是流套接字,因此只要确保
recv()
/
read()
调用使用大小非零的缓冲区,零返回表示对等方已执行有序关闭

有序关机是两件事之一:关闭套接字或调用它(在这种情况下,使用SHUT_WR或SHUT_RDWR,前者表示它不会发送任何进一步的数据,但能够接收,后者表示它不会发送或接收任何数据)。

是。返回值部分对此进行了说明:

这些调用返回接收的字节数,如果 发生错误。发生错误时,errno设置为 指出错误

当流套接字对等方执行有序关闭时 返回值将为0(传统的“文件结束”返回)

不同域(如UNIX和Internet)中的数据报套接字 域)允许零长度数据报。当这样的数据报 接收时,返回值为0

如果请求的字节数不正确,也可能返回值0 从流套接字接收的值为0

TCP套接字是流套接字,因此只要确保
recv()
/
read()
调用使用大小非零的缓冲区,零返回表示对等方已执行有序关闭


有序关机是两件事之一:关闭套接字或调用它(在这种情况下,使用SHUT_WR或SHUT_RDWR,前者表示它不会发送任何进一步的数据,但能够接收,后者表示它不会发送或接收任何数据)。

不,这不是一个健壮的解决方案,原因有二

首先,对于连接的TCP套接字,
read
recv
将返回零,而不是零−1,在读取所有传入数据且远程对等方已关闭其连接端(使用
关闭
关闭
)之后。您的
已连接
在这种情况下将返回TRUE,这是错误的

第二,说(描述的第二段;全部强调我的)

在采取下述任何操作之前,如果
nbyte
为零,则
read
功能可能会检测并返回下述错误。在没有错误的情况下,或者如果没有执行错误检测,
读取功能应返回零,并且没有其他结果

nbyte
是第三个参数,您的
IsConnected
提供的参数为零。因此,根据操作系统的不同,
IsConnected
可能总是返回TRUE,而不管套接字的状态如何

如果
length
参数(相当于
read
nbyte
)为零,则没有说明会发生什么;我认为这可能是一个疏忽,它(以及
recvfrom
recvmsg
,等等)与
read
具有相同的特殊行为。因此,将
read
更改为
recv
本身并不能解决问题。但是,我认为通过将
recv
MSG_PEEK
一起使用,可以实现完全修复:

bool is_connected(int sock)
{
    char dummy[1];
    ssize_t nread = recv(sock, dummy, sizeof dummy, MSG_PEEK);
    if (nread > 0)
        return true;    // at least one byte of data available
    else if (nread == 0)
        return false;   // EOF
    else
        return errno == EWOULDBLOCK || errno == EAGAIN;
}
使用
MSG_PEEK
可以提供非零长度,因为数据实际上不会被消耗


根据应用程序及其网络协议的细节,您也可以考虑在Socket上。

不,这不是一个健壮的解决方案,原因有两个:

首先,对于连接的TCP套接字,
read
recv
将返回零,而不是零−1,在读取所有传入数据且远程对等方已关闭其连接端(使用
关闭
关闭
)之后。您的
已连接
在这种情况下将返回TRUE,这是错误的

第二,说(描述的第二段;全部强调我的)

在采取下述任何操作之前,如果
nbyte
为零,则
read
功能可能会检测并返回下述错误。在没有错误的情况下,或者如果没有执行错误检测,
读取功能应返回零,并且没有其他结果

nbyte
是第三个参数,您的
IsConnected
提供的参数为零。因此,根据操作系统的不同,
IsConnected
可能总是返回TRUE,而不管套接字的状态如何

如果
length
参数(相当于
read
nbyte
)为零,则没有说明会发生什么;我认为这可能是一个疏忽,它(以及
recvfrom
recvmsg
,等等)与
read
具有相同的特殊行为。因此,将
read
更改为
recv
本身并不能解决问题。然而,我认为通过使用
recv完全修复是可能的<