У меня есть что-то вроде этого:
#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;
}
Я ожидал, что строка «Таймер истек» будет напечатана хотя бы один раз (TimeConnected был инициализирован в одно из условий if) во время выполнения,но по какой-то причине он никогда не распечатывается.Я думал, что мой цикл while должен продолжать печатать его ... Кто-нибудь знает, если я что-то напутал?
РЕДАКТИРОВАТЬ: На самом деле я использую таймер, чтобы отключить время после тайм-аута.Я только что заметил, что он печатает «Таймер истек», если другой клиент подключается к серверу.Я передал последний параметр для выбора, но не уверен, почему он не оказывает никакого влияния.
Благодаря bdk !!Если вам интересно знать «глупую» ошибку, которая была у меня в этом коде, прочитайте подробное обсуждение ниже ... Это была очевидная ошибка, которую я упустил из виду ... все из-за одного предложения в уроках: "select modizesваши оригинальные дескрипторы ".
Список изменений:
- Обратите внимание, что набор операторов 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;
}