检查连接是否打开或关闭?(在Linux中为C)
在Linux中的套接字编程中我需要在套接字中写入数据,但我不知道套接字是打开还是关闭。如何知道该套接字是打开并关闭而未读取的?检查连接是否打开或关闭?(在Linux中为C)
printf("befor read%d\n", n);
bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
break;
}
printf("befor write%d, s: %d \n", n , sockfd);
n = write(newsockfd, buffer, n);
if (n <= 0)
{
break;
}
我从sockfd读取,我确信这个连接是打开的。何时在newsockfd中写缓冲区我不知道newsockfd是打开还是关闭如何检查newsockfd是否已关闭?
我知道问题。在书写连接中间关闭。例如在500个连接关闭并写入程序时写入1024个数据。如何避免这一点?
我使用发送()代替写(),该处理没有信号:
bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
break;
}
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL);
if (n2 == -1)
{
close(sockfd);
close(newsockfd);
return;
}
if (n2 != n)
{
break;
}
中的下一行
检查,如果你可以写一个插座,奇怪的是,尝试如果已经关闭了套接字写吧:-)
的样子,你会从write
,你会得到一个-1
返回码可以检查errno
以查看问题所在。
如果套接字仍然有效,但你不能在此刻写入任何数据,write
将返回0。read
通话也表现在以类似的方式,返回-1
如果有一个问题。
基本上,write
:
- ,如果你得到一个
-1
,还有的是一个问题,你应该检查errno
,看它是否是可回收或可致命。 - 如果你找回
0
,那么你现在不能写任何东西(可能是网络积压或其他问题,但绝对不是(致命的))。 - 如果您获得的价值低于您的要求,那么部分的数据已发送。调整你的指针,这样你可以尝试在下一个周期中发送剩下的指针。如果不是假定正返回值表示整个块已经发送。
- 如果您返回的数字与您尝试发送的字节数相同,则整个缓冲区已被接受发送。
- 如果您回复的内容超过您要求发送的内容,请发送电子邮件给内核开发人员,并提供一些尖锐的评论。莱纳斯等人会喜欢:-)
更新:作为非洲足联在评论中指出,我忘了考虑到信号处理。您必须忽略破损的管道信号,否则write
将通过提升该信号而在内部失效。
您可以通过插入这样做:
struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);
开始使用socket函数之前。然后您可以使用:
sigaction (SIGPIPE, &old_actn, NULL);
恢复以前的信号处理。
套接字编程可能相当棘手,因为您经常不知道直到很晚才发生错误。例如,如果您正在写入的机器异常关闭,则写入调用可能成功(因为您可以写入内部OS缓冲区),只能在关闭调用期间失败。
除非您有验证套接字的应用层方法是活动的(即发送消息并在一段时间内要求响应),否则您无法知道。如果您使用的是标准协议,则可能已经存在处理错误的内容。
所以简短的回答是,你需要检查几乎所有接触套接字(读,写,关闭等)的调用返回的错误。
不幸的是,这是正确的答案。我尝试了几种方法来确定保持活动的HTTP连接是否仍然有效,但它不可靠,没有竞争条件。 – Lothar 2014-04-22 22:41:07
这会起作用,另一种选择是使用'sigaction'来忽略'SIGPIPE'(将其处理程序设置为'SIG_IGN')。 – caf 2009-11-25 12:42:56