gpt4 book ai didi

c++ - select() 总是返回 1; C++中的TCP连接套接字问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:20:58 31 4
gpt4 key购买 nike

我正在做一个 C++ 项目,它要求服务器在每次 accept() 返回一个新的套接字描述符时创建一个新线程来处理连接。我正在使用 select 来决定何时进行连接尝试以及客户端何时通过新创建的客户端套接字(接受创建的套接字)发送数据。所以两个函数和两个选择 - 一个用于轮询专用于监听连接的套接字,一个用于轮询在新连接成功时创建的套接字。

第一种情况的行为是我所期望的 - FD_ISSET 仅在请求连接时为我的监听套接字的 ID 返回 true,并且在下一次连接尝试之前返回 false。第二种情况不起作用,即使代码与不同的 fd_set 和 socket 对象完全相同。我想知道这是否源于 TCP 套接字?由于它们的流动性,这些套接字在被 select 轮询时是否总是返回 true?

//working snippet

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500000;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sid,&readfds);

//start server loop
for(;;){

//check if listening socket has any client requrests, timeout at 500 ms
int numsockets = select(sid+1,&readfds,NULL,NULL,&tv);
if(numsockets == -1){
if(errno == 4){
printf("SIGINT recieved in select\n");
FD_ZERO(&readfds);
myhandler(SIGINT);
}else{
perror("server select");
exit(1);
}
}

//check if listening socket is ready to be read after select returns
if(FD_ISSET(sid, &readfds)){
int newsocketfd = accept(sid, (struct sockaddr*)&client_addr, &addrsize);
if(newsocketfd == -1){
if(errno == 4){
printf("SIGINT recieved in accept\n");
myhandler(SIGINT);
}else{
perror("server accept");
exit(1);
}
}else{
s->forkThreadForClient(newsocketfd);
}
}






//non working snippet

//setup clients socket with select functionality
struct timeval ctv;
ctv.tv_sec = 0;
ctv.tv_usec = 500000;
fd_set creadfds;
FD_ZERO(&creadfds);
FD_SET(csid,&creadfds);



for(;;){

//check if listening socket has any client requrests, timeout at 500 ms
int numsockets = select(csid+1,&creadfds,NULL,NULL,&ctv);
if(numsockets == -1){
if(errno == 4){
printf("SIGINT recieved in client select\n");
FD_ZERO(&creadfds);
myhandler(SIGINT);
}else{
perror("server select");
exit(1);
}
}else{
printf("Select returned %i\n",numsockets);
}

if(FD_ISSET(csid,&creadfds)){


//read header
unsigned char header[11];
for(int i=0;i<11;i++){
if(recv(csid, rubyte, 1, 0) != 0){
printf("Received %X from client\n",*rubyte);
header[i] = *rubyte;
}
}

如有任何帮助,我们将不胜感激。


感谢您的回复,但我认为这与循环内的超时值没有太大关系。我测试了它,即使每次服务器循环时 tv 被重置并且 fd_set 被清零,select 仍然立即返回 1。我觉得 select 如何处理我的 TCP 套接字存在问题。每当我设置选择最高套接字 ID 以包含我的 TCP 套接字时,它会立即返回该套接字集。此外,客户端不发送任何内容,只是连接。

最佳答案

必须做的一件事是每次调用select() 之前将tv 的值重置为您想要的超时。 select() 函数会更改 tv 中的值,以指示从函数返回后超时还剩多少时间。如果您不这样做,您的 select() 调用将以零超时结束,这是低效的。

其他一些操作系统以不同方式实现select(),它们不会更改tv 的值。 Linux 确实会更改它,因此您必须重新设置它。

关于c++ - select() 总是返回 1; C++中的TCP连接套接字问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4790996/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com