在Linux中的套接字编程中,我需要用socket编写数据,但我不知道套接字是打开的还是关闭的。我怎么知道套接字是打开和关闭的,没有读?
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个数据。如何避免这种情况?
发布于 2009-11-25 09:02:44
我使用send()代替了write(),它不处理任何信号:
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;
}发布于 2009-11-25 07:25:20
令人惊讶的是,检查是否可以写入套接字的方法是尝试写到它:-)
如果套接字已经关闭,您将从write获得一个write返回代码,您可以检查errno以查看问题所在。
如果套接字仍然有效,但目前无法写入任何数据,write将返回0。read调用也以类似的方式运行,如果出现问题,则返回-1。
基本上,对于write
-1,你应该检查它是可恢复的还是致命的。如果你拿回一个0,那么你现在什么都不能写(可能是网络积压或者其他问题,但肯定不是致命的)。如果你得到的值低于你想要的值,那么就发送了一些数据。调整您的指针,以便您可以尝试发送其余在下一个周期。不要假设返回值为正,这意味着整个块已经发送。更新:正如caf在评论中指出的,我忘了考虑信号处理。您必须忽略已损坏的管道信号,否则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);在开始使用套接字函数之前。然后,您可以使用:
sigaction (SIGPIPE, &old_actn, NULL);若要恢复先前的信号处理,请执行以下操作。
发布于 2009-11-25 07:30:10
套接字编程可能相当棘手,因为您通常直到很久以后才知道发生了错误。
例如,如果您要写入的机器不正常地关闭,写调用可能会成功(因为您能够写入您的内部OS缓冲区),但在关闭调用期间失败。
除非您有验证套接字处于活动状态的应用层方法(即发送消息并要求在某个时间段内作出响应),否则您无法知道。如果您使用的是标准协议,则可能已经存在一些用于处理错误的内容。
因此,简单的回答是,您需要检查每个与套接字有关的调用(读、写、关闭等)中的错误返回。)。
https://stackoverflow.com/questions/1795193
复制相似问题