[英]C socket programming: client send() but server select() doesn't see it
[英]TCP client socket, doesn't block on select()
以下代码是为了解 TCP 客户端程序中select()
调用的行为而编写的测试程序。
我观察到的是 select 没有阻塞,而是程序在recv()
上阻塞。 output如下:
Wait on select.
Wait on recv.
...
我的问题是为什么select()
返回成功? 理想情况下,它应该阻塞select()
而不是recv()
。
TCP服务器每3秒发送一次15字节的字符串。
int clientfd = -1;
int dummyfd = -1;
int maxfd = -1;
struct sockaddr_in server_addr;
char recv_buf[100] = {0};
int msg_len = 0;
int bytes_recv = 0;
fd_set readfd;
int retval = 0;
/* Open the socket and a dummy socket */.
clientfd = socket(AF_INET, SOCK_STREAM, 0);
dummyfd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == clientfd || -1 == dummyfd)
{
perror("socket error: ");
exit(1);
}
printf("Socket opened : %d\n", clientfd);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(10000);
//server_addr.sin_addr.s_addr = INADDR_ANY;
inet_aton("127.0.0.1", &(server_addr.sin_addr));
memset(&(server_addr.sin_zero), 0, 8);
/* Connect to server */
if(connect(clientfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
{
perror("connect error: ");
exit(1);
}
printf("Connect Success\n");
maxfd = (clientfd > dummyfd) ? (clientfd + 1) : (dummyfd + 1);
while(1)
{
FD_ZERO(&readfd);
FD_SET(clientfd, &readfd);
FD_SET(dummyfd, &readfd);
printf("Wait on select\n");
retval = select(maxfd , &readfd, NULL, NULL, NULL);
if(retval <= 0)
{
printf("select failed\n");
}
else
{
printf("Wait on recv\n");
/* ... The process waits here ... */
bytes_recv = recv(clientfd, recv_buf, 100, 0);
printf("%d: Bytes recv = %d\t%s\n", retval, bytes_recv, recv_buf);
memset(recv_buf, 0 ,100);
}
}
close(clientfd);
return 0;
}
编辑:没有 dummyfd,程序按预期工作。 一个后续问题:
当服务器突然关闭时,如何使用select()
检测到这一点?
当服务器端崩溃时,可以修改程序以便在select()
上阻塞吗?
使用以下内容确保它是从clientfd
返回的select
:
else if (FD_ISSET(clientfd, &readfd)) {
没有时间测试,但我怀疑dummyfd
是作为 EOF 从 select 而不是clientfd
的。
select() 返回后,您将希望有条件地从 clientfd 接收。 我的猜测是 dummyfd 上可能有数据触发 select 完成,但接收在 clientfd 上。
retval = select(maxfd , &readfd, NULL, NULL, NULL);
if(retval <= 0)
{
printf("select failed\n");
}
else
{
if (FD_ISSET(clientfd, &readfd))
{
bytes_recv = recv(clientfd, recv_buf, 100, 0);
...
}
if (FD_ISSET(dummyfd, &readfd))
{
/* "dummyfd" processing */
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.