gpt4 book ai didi

c++ - 从一端关闭的管道或套接字对读取直到达到 EOF 是否安全?

转载 作者:行者123 更新时间:2023-11-30 17:29:56 25 4
gpt4 key购买 nike

考虑以下示例代码:

#include <sys/socket.h>

int main()
{
int sv[ 2 ] = { 0 };
socketpair( AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, sv );

for( unsigned ii = 0; ii < 5; ++ii )
{
int* msg = new int( 123 );
if( -1 == send( sv[ 0 ], &msg, sizeof(int*), MSG_NOSIGNAL ) )
{
delete msg;
}
}

close( sv[0] );
sleep( 1 );

int* msg = 0;
int r;
while( ( r = read( sv[ 1 ], &msg, sizeof(int*) ) ) > 0 )
{
delete msg;
}

return 0;
}

显然,代码运行良好,但这并不意味着它不是 UB。

在手册页中找不到任何内容,这保证了当sv[ 0 ]时关闭后,read仍然能够读取 sv[ 1 ] 中的所有内容,由 send 发送.

<小时/>

也许这个问题可以这样问 - as read返回0对于 EOF并作为 socketpairSOCK_STREAM ,我期望EOF一旦从套接字读取所有内容并且另一侧关闭,就会“命中”。这是正确的吗?

最佳答案

据我所知,它可以工作,但闻起来有UB的味道。

正确的方法是正常关闭:

  • shutdown(s, 1) 或(更好的shutdown(s, SHUT_WR))
  • 读取直到输入结束
  • 然后才调用 close。

(引用文献:http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspxGraceful Shutdown Server Socket in Linux)

编辑:

读完 R.. 评论后,我想我是否有点困惑,做了一些测试并再次阅读文档。而且...我现在认为我所说的对于一般套接字使用(包括 AF_INET 套接字)是正确的,但对于特殊的 AF_INET 套接字对则不然。

我的测试对系统施加了更大的压力,因为我在 FreeBSD 9 系统上发送了 8 个 1024 字节的数据包。我停在那里,因为发送更多内容会被阻止。在 sv[0] 关闭后,我可以成功读取我的 8 个数据包。

因此它可以在不同的内核上运行,但无法找到有效的引用,除了 AF_UNIX 套接字不支持 OOB 数据。

我还可以确认使用关闭功能可以正常工作。

结论:就我而言,我会坚持使用优雅关闭来关闭套接字,但主要是因为我不想考虑底层协议(protocol)。

希望有更多知识的人可以提供一份引用文档

关于c++ - 从一端关闭的管道或套接字对读取直到达到 EOF 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25446975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com