Saj*_*ani 10 c sockets linux network-programming
在Linux中的套接字编程中我需要在socket中写入数据,但我不知道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;
}
Run Code Online (Sandbox Code Playgroud)
我从sockfd读到,我确定这个连接是开放的.什么时候在newsockfd写缓冲区我不知道newsockfd是打开还是关闭如何检查newsockfd是否关闭?
我知道问题.在写连接中间关闭.例如,在500连接关闭和程序关闭时写入1024个数据.怎么避免这个?
pax*_*blo 17
令人惊讶的是,检查是否可以写入套接字的方法是尝试写入它:-)
如果套接字已关闭,您将从中获取-1返回代码write,您可以检查errno以查看问题所在.
如果套接字仍然有效,但您此刻无法写入任何数据,write则返回0.该read调用也以类似的方式运行,-1如果出现问题则返回.
基本上,对于write:
-1,那就出现了问题,你应该检查errno它是否可以恢复或致命.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);
Run Code Online (Sandbox Code Playgroud)
在开始使用套接字函数之前.然后你可以使用:
sigaction (SIGPIPE, &old_actn, NULL);
Run Code Online (Sandbox Code Playgroud)
恢复以前的信号处理.
Saj*_*ani 14
我使用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;
}
Run Code Online (Sandbox Code Playgroud)
套接字编程可能相当棘手,因为您经常不知道错误发生在很久以后.
例如,如果您要写入的计算机异常关闭,则写入调用可能会成功(因为您可以写入内部OS缓冲区),但只能在关闭调用期间失败.
除非你有一个应用程序层方式来验证套接字是否处于活动状态(即发送消息并在一段时间内要求响应),否则你无法知道.如果您使用的是标准协议,则可能已存在某些内容来处理错误.
所以简短的回答是你需要检查几乎所有触及套接字的调用(读,写,关闭等)的错误返回.