我试图编写一个实验性的客户端/服务器程序,以证明写入失败或阻止发送缓冲区已满。 基本上,我在发送程序上有一个无限循环,我使用select()来检查我是否可以在缓冲区上写入(我认为这意味着套接字缓冲区不是满的),如果我可以在缓冲比我写()一个字符。当FD_ISSET(sockfd,& writefds)为假时,循环中断(我无法写入缓冲区,因为它已满)。 在开始阅读()之前,接收程序正在休眠一分钟。我希望发送者能够在这个休眠时间内填充缓冲区,但实际上,程序永远不会结束。
发件人:
int main(int argc, char *argv[]) {
char buffer[100];
int sockfd, total = 0, bytes = 0;
fd_set writefds;
sockfd = dial(argv[1], argv[2]);
bzero(buffer, sizeof buffer);
while(1)
{
int ret = 0;
FD_ZERO(&writefds);
FD_SET(sockfd, &writefds);
if((ret = select(sockfd + 1, NULL, &writefds, NULL, 0)) < 0)
{
perror("select");
exit(errno);
}
if(FD_ISSET(sockfd, &writefds))
{
write(sockfd, "a", 1);
total++;
continue;
}
else
{
puts("I can't write in the socket buffer");
break;
}
}
printf("nb chars written: %d\n", total);
return 0;
}
reciever:
int foo(int sockfd) {
char buffer[100];
int t, total = 0;
bzero(buffer, sizeof buffer);
printf("I have a new client\n");
sleep(60);
while((t = read(sockfd, buffer, sizeof buffer)) > 0)
{
total += t;
printf("%d ", total);
}
printf("nb chars read: %d\n", total);
if(t < 0)
{
perror("read");
}
printf("I don't have that client anymore\n");
return 0;
}
答案 0 :(得分:0)
你在正确的轨道上,但套接字发送缓冲区可能是48k或更多。这是很多迭代。尝试一次写8k,而不只是一个字节。并且在接收器读取之前增加时间。
NB没有必要对此进行测试。它在阻塞模式下阻塞,并在非阻塞模式下以EAGAIN / EWOULDBLOCK失败。请参阅 man 页面。
答案 1 :(得分:0)
您的选择超时为空,因此select()
将在发送缓冲区已满时阻止。这意味着当它返回时,套接字是可写的,你永远不会得到你的代码“我不能在套接字缓冲区中写”。
参见手册页http://linux.die.net/man/2/select
如果你想要零超时,即不要阻塞select()
,你需要将指针传递给时间结构,两个字段都设置为零。