我是C套接字编程的新手,我正在尝试使用select(...)来实现客户端 - 服务器非阻塞应用程序。
当我运行调试服务器代码并尝试连接客户端时,select(...)返回1(如预期的那样)但由于某种原因,FD_ISSET在描述符集中找不到文件描述符ID
我已经花了好几天的时间进行调试,而且我的想法已经不多了。 任何帮助将不胜感激!
void server_listen(int port_number){
tcpsock_t * server, * client;
fd_set master_set, working_set;
int listen_sd;
int max_sd, rc, desc_ready, bytes, result, close_conn;
dplist_node_t * reference;
if (tcp_passive_open(&server,PORT)!=TCP_NO_ERROR) exit(EXIT_FAILURE);
if (tcp_get_sd(server,&listen_sd)!=TCP_NO_ERROR) exit(EXIT_FAILURE);
FD_ZERO(&master_set);
max_sd = listen_sd;
FD_SET(listen_sd, &master_set);
do {
timeout.tv_sec = 30;
timeout.tv_usec = 0;
memcpy(&working_set, &master_set, sizeof(master_set));
printf("Waiting on select()...\n");
rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);
if (rc < 0)
{
perror(" select() failed");
break;
}
if (rc == 0)
{
printf(" select() timed out.\n");
}
desc_ready = rc;
for (int i=1; i <= max_sd && desc_ready > 0; ++i)
{
if (FD_ISSET(i, &working_set))
{
desc_ready -= 1;
if (i == listen_sd)
{
printf(" Listening socket is readable\n");
//do something with the new socket
}
}
else
{
printf(" Descriptor %d is readable\n", i);
close_conn = FALSE;
//read data from already existing socket connection
} /* End of existing connection is readable */
} /* End of if (FD_ISSET(i, &working_set)) */
}
while (end_server == FALSE);
}
int tcp_passive_open(tcpsock_t ** sock, int port)
{
int result;
struct sockaddr_in addr;
tcpsock_t * s = (tcpsock_t *) malloc(sizeof(tcpsock_t));
s->cookie = 0;
s->port = -1;
s->ip_addr = NULL;
s->sd = -1;
s->sd = socket(PROTOCOLFAMILY, TYPE, PROTOCOL);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = PROTOCOLFAMILY;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
result = bind(s->sd,(struct sockaddr *)&addr,sizeof(addr));
result = listen(s->sd,MAX_PENDING);
s->ip_addr = NULL;
s->port = port;
s->cookie = MAGIC_COOKIE;
*sock = s;
return TCP_NO_ERROR;
}
int tcp_get_sd(tcpsock_t * socket, int * sd)
{
*sd = socket->sd;
return TCP_NO_ERROR;
}
答案 0 :(得分:1)
你的for循环从1开始。如果min-height: 100px
回到0,你的循环就会失败。
所以,改变:
listen_sd
分为:
for (int i=1; i <= max_sd && desc_ready > 0; ++i)
此外,只使用一个文件描述符,您根本不需要for循环。
<强>更新强>
由于您已发布for (int i=0; i <= max_sd && desc_ready > 0; ++i)
个功能,我可以进一步发表评论。因为您不显示tcp_*
,PROTOCOLFAMILY
和TYPE
是什么,所以他们是可疑的。
由于您遇到问题,请检查PROTOCOL
,socket
和bind
的返回值是否有任何错误。
有关简单工作的客户端/服务器应用程序的示例,请参阅我的答案:executing commands via sockets with popen()