gpt4 book ai didi

C: select()下部分代码不执行

转载 作者:行者123 更新时间:2023-11-30 14:31:01 25 4
gpt4 key购买 nike

我有这样的东西:

#define QUIT_TIME 5
int main(int argc, char **argv) {
//... SOCKETS STUFF ....
fdmax = parentfd;


while (notdone) {

//Set the timers
waitd.tv_sec = 1;
waitd.tv_usec = 0;

FD_ZERO(&tempreadfds);
FD_ZERO(&tempwritefds);

FD_ZERO(&readfds); /* initialize the read fd set */
FD_ZERO(&writefds); /* initialize the write fd set */

FD_SET(parentfd, &readfds); /* add listener socket fd */
FD_SET(0, &readfds); /* add stdin fd (0) */

tempreadfds = readfds; //make a copy
tempwritefds = writefds; //make a copy

if (select(fdmax+1, &tempreadfds, &tempwritefds, (fd_set*) 0, &waitd) < 0) {
error("ERROR in select");
}

for(i = 1; i <= fdmax; i++) {

if(FD_ISSET(i, &readfds)) {
if(i == parentfd) {
//This is a new connection
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
if (childfd < 0)
error("ERROR on accept");

InitializeDataStructures(childfd);

FD_SET(childfd, &readfds); //add to the master set
if(childfd > fdmax)
fdmax = childfd;
} else {
//Existing connection
if((nBytes = read(i, connections[i].buffer, MAXBUFFER)) <= 0) {
if(nBytes == 0) {
//Connection closed
printf("Socket %d hung up\n", read_write_loop);
} else {
error("\nReceive error\n");
}

FD_CLR(i, &readfds);
} else {
//We have some data from the connection
//... Manipulate the buffer
//Handle the message
}
}
}

if(FD_ISSET(i, &writefds)) {
.....
FD_CLR(i, &writefds);
}

//Timer checking
if(connections[i].active) {
gettimeofday(&TimeNow, NULL);
timeval_diff(&Interval, &TimeNow, &connections[i].TimeConnected);
printf("*_*_*__*_*_*__*_*_*_*_* difference is %ld seconds, %ld microseconds\n",
Interval.tv_sec,
Interval.tv_usec
);
if(Interval.tv_sec >= QUIT_TIME) {
printf("Timer elapsed!!\n");
}
}

}
}

/* clean up */
printf("Terminating server.\n");
close(parentfd);
return 0;
}

void InitializeDataStructures(int i) {

clients[i].active = YES;
clients[i].fd = i;
//Initialize other members of the structure
}

long long timeval_diff(struct timeval *difference, timeval *end_time, struct timeval *start_time) {
struct timeval temp_diff;

if(difference==NULL)
difference=&temp_diff;

difference->tv_sec =end_time->tv_sec -start_time->tv_sec ;
difference->tv_usec=end_time->tv_usec-start_time->tv_usec;

while(difference->tv_usec<0)
{
difference->tv_usec+=1000000;
difference->tv_sec -=1;
}

return 1000000LL*difference->tv_sec + difference->tv_usec;

}

我期望在执行期间至少打印一次“Timer elapsed”行(TimeConnected 被初始化为 if 条件之一),但由于某种原因,它永远不会打印出来。我认为我的 while 循环应该继续打印它...有人知道我是否在某个地方搞砸了吗?

编辑:实际上,我正在使用计时器在超时后断开时间。我刚刚观察到,如果另一个客户端连接到服务器,它会打印“计时器已过”。我确实将最终参数传递给了 select,但不确定为什么它没有任何效果。

感谢bdk!!如果您有兴趣了解我在这段代码中遇到的“愚蠢”错误,请详细阅读下面的讨论...这是一个明显的错误,我忽略了...这一切都是因为教程中的一句话:“选择修改你的原始描述符”。

更改列表:

  • 请注意,一组 FD_ZERO 语句被错误地放置在 while 循环内
  • FD_ISSET 正在传递 readfds 和 writefds,而不是 tempreadfds 和 tempwritefds...

工作代码:

#define QUIT_TIME 5
int main(int argc, char **argv) {
//... SOCKETS STUFF ....
fdmax = parentfd;


FD_ZERO(&readfds); /* initialize the read fd set */
FD_ZERO(&writefds); /* initialize the write fd set */

while (notdone) {

//Set the timers
waitd.tv_sec = 1;
waitd.tv_usec = 0;

FD_ZERO(&tempreadfds);
FD_ZERO(&tempwritefds);


FD_SET(parentfd, &readfds); /* add listener socket fd */
FD_SET(0, &readfds); /* add stdin fd (0) */

tempreadfds = readfds; //make a copy
tempwritefds = writefds; //make a copy

if (select(fdmax+1, &tempreadfds, &tempwritefds, (fd_set*) 0, &waitd) < 0) {
error("ERROR in select");
}

for(i = 1; i <= fdmax; i++) {

if(FD_ISSET(i, &tempreadfds)) {
if(i == parentfd) {
//This is a new connection
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
if (childfd < 0)
error("ERROR on accept");

InitializeDataStructures(childfd);

FD_SET(childfd, &readfds); //add to the master set
if(childfd > fdmax)
fdmax = childfd;
} else {
//Existing connection
if((nBytes = read(i, connections[i].buffer, MAXBUFFER)) <= 0) {
if(nBytes == 0) {
//Connection closed
printf("Socket %d hung up\n", read_write_loop);
} else {
error("\nReceive error\n");
}

FD_CLR(i, &readfds);
} else {
//We have some data from the connection
//... Manipulate the buffer
//Handle the message
}
}
}

if(FD_ISSET(i, &tempwritefds)) {
.....
FD_CLR(i, &writefds);
}

//Timer checking
if(connections[i].active) {
gettimeofday(&TimeNow, NULL);
timeval_diff(&Interval, &TimeNow, &connections[i].TimeConnected);
printf("*_*_*__*_*_*__*_*_*_*_* difference is %ld seconds, %ld microseconds\n",
Interval.tv_sec,
Interval.tv_usec
);
if(Interval.tv_sec >= QUIT_TIME) {
printf("Timer elapsed!!\n");
}
}

}
}

/* clean up */
printf("Terminating server.\n");
close(parentfd);
return 0;
}

void InitializeDataStructures(int i) {

clients[i].active = YES;
clients[i].fd = i;
//Initialize other members of the structure
}

long long timeval_diff(struct timeval *difference, timeval *end_time, struct timeval *start_time) {
struct timeval temp_diff;

if(difference==NULL)
difference=&temp_diff;

difference->tv_sec =end_time->tv_sec -start_time->tv_sec ;
difference->tv_usec=end_time->tv_usec-start_time->tv_usec;

while(difference->tv_usec<0)
{
difference->tv_usec+=1000000;
difference->tv_sec -=1;
}

return 1000000LL*difference->tv_sec + difference->tv_usec;

}

最佳答案

看看你选择的循环参数,它们对我来说看起来很可疑。主要是您在 tempreadfd 和 tempwritefd 上调用 select,但是当您调用 FD_ISSET 时,您将其传递给 readfd 和 writefd。在调用 select 之前,您使用 FD_SET 来设置您感兴趣的所有 fd。由于这些变量没有被发送到 select,因此未触发的 fd 不会被屏蔽。因此,您将在所有描述符上检测到“事件”。该接受描述符上确实没有任何事件,因此它会阻塞,直到有新客户端连接为止。

至少这是我的猜测。

关于C: select()下部分代码不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2189121/

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