select函数有时会改变第二个参数readfds的值吗
Does the select function change the value of the second argument readfds sometimes
这是代码:
FD_ZERO(&t_set);
num = 0;
maxfd = 0;
while (num < MAX)
{
if ((sockfd = connectSocket(ptr)))
;
//printf("connect to server succeed!\n%d\n", fd);
else
{
fprintf(stderr, "connect error\n");
exit(1);
}
if (!writeSocket(sockfd, ptr))
;
//printf("write to server succeed!\n");
else
{
fprintf(stderr, "write error\n");
exit(1);
}
if (maxfd < sockfd)
maxfd = sockfd;
FD_SET(sockfd, &t_set);
printf("%d\n", t_set);
memset(fileName, 0, BUFSIZE);
sprintf(fileName,"%d.html", sockfd);
if ((filefd = open(fileName, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == -1)
{
printf("create file failed!\n");
return -1;
}
ff[num].sockfd = sockfd;
ff[num].filefd = filefd;
++num;
}
printf(">------------------->\n");
while (1)
{
//sleep(1);
tv.tv_sec = 1;
tv.tv_usec = 0;
h = 0;
printf("%d\n", t_set); //print the t_set before select
h = select(maxfd + 1, &t_set, NULL, NULL, &tv);
printf("%d\n", t_set); //print the t_set after select
printf(">------------------->\n");
//fd_set is an array of long;
//if use printf("%d %d", t_set, h); secondly may print the second value of t_set , not h;
if (h < 0)
{
fprintf(stderr, "select error");
return -1;
}
if (h == 0)
{
fprintf(stderr, "select return 0\n");
break;
}
else
{
int n = 0;
while (!FD_ISSET(ff[n].sockfd, &t_set))
++n;
if (readSocket(ff[n].sockfd, ff[n].filefd))
{
FD_CLR(ff[n].sockfd, &t_set);
printf("===================== %d\n", n);
}
}
}
num = 0;
while (num++ < MAX)
close(ff[num].filefd);
输出:
8 // initial of t_set
40
168
680
2728
>------------------->
2728 // the two value were print before and after the select;
680
>------------------->
680
680
>------------------->
680
680
>------------------->
680
680
打印t_set的值,我发现在第一个和最后一个循环调用select后t_set的值被改变了。
如果在select前加上sleep(1),设置tv_set.sec = 0,tv_usec = 0,用sleep timeout代替select超时,t_set执行正常。
还有一个问题,上面的例子无法监听到最后一个socket,使用sleep change也可以修复问题;
如有任何建议,我们将不胜感激!
来自 select(2) 手册页:
"On exit, the sets [that is, readfs
, writefds
, and exceptfds
] are modified in place to indicate which file descriptors actually changed status."
您只使用了readfs
,但应该被select
系统调用修改。
这是代码:
FD_ZERO(&t_set);
num = 0;
maxfd = 0;
while (num < MAX)
{
if ((sockfd = connectSocket(ptr)))
;
//printf("connect to server succeed!\n%d\n", fd);
else
{
fprintf(stderr, "connect error\n");
exit(1);
}
if (!writeSocket(sockfd, ptr))
;
//printf("write to server succeed!\n");
else
{
fprintf(stderr, "write error\n");
exit(1);
}
if (maxfd < sockfd)
maxfd = sockfd;
FD_SET(sockfd, &t_set);
printf("%d\n", t_set);
memset(fileName, 0, BUFSIZE);
sprintf(fileName,"%d.html", sockfd);
if ((filefd = open(fileName, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == -1)
{
printf("create file failed!\n");
return -1;
}
ff[num].sockfd = sockfd;
ff[num].filefd = filefd;
++num;
}
printf(">------------------->\n");
while (1)
{
//sleep(1);
tv.tv_sec = 1;
tv.tv_usec = 0;
h = 0;
printf("%d\n", t_set); //print the t_set before select
h = select(maxfd + 1, &t_set, NULL, NULL, &tv);
printf("%d\n", t_set); //print the t_set after select
printf(">------------------->\n");
//fd_set is an array of long;
//if use printf("%d %d", t_set, h); secondly may print the second value of t_set , not h;
if (h < 0)
{
fprintf(stderr, "select error");
return -1;
}
if (h == 0)
{
fprintf(stderr, "select return 0\n");
break;
}
else
{
int n = 0;
while (!FD_ISSET(ff[n].sockfd, &t_set))
++n;
if (readSocket(ff[n].sockfd, ff[n].filefd))
{
FD_CLR(ff[n].sockfd, &t_set);
printf("===================== %d\n", n);
}
}
}
num = 0;
while (num++ < MAX)
close(ff[num].filefd);
输出:
8 // initial of t_set
40
168
680
2728
>------------------->
2728 // the two value were print before and after the select;
680
>------------------->
680
680
>------------------->
680
680
>------------------->
680
680
打印t_set的值,我发现在第一个和最后一个循环调用select后t_set的值被改变了。 如果在select前加上sleep(1),设置tv_set.sec = 0,tv_usec = 0,用sleep timeout代替select超时,t_set执行正常。 还有一个问题,上面的例子无法监听到最后一个socket,使用sleep change也可以修复问题;
如有任何建议,我们将不胜感激!
来自 select(2) 手册页:
"On exit, the sets [that is, readfs
, writefds
, and exceptfds
] are modified in place to indicate which file descriptors actually changed status."
您只使用了readfs
,但应该被select
系统调用修改。