Ho un problema con la funzione select quando ho lavorato su un programma socket Linux. La funzione select ha funzionato bene come dice la pagina man se il client ha collegato il lato server nell'intervallo di tempo configurato dal server. Se si verifica il timeout, la funzione di selezione restituirà 0 per sempre. A quel tempo, eseguo il debug del client e trovo che il client si sia connesso al server. Ma la funzione di selezione restituisce ancora 0. Ho cercato questo problema ma non ne trovai nessuna utile. Qualcuno potrebbe sapere perché selezionare ha fatto così? La mia versione di Linux è RHEL5.4. Grazie per l'aiuto.perché select() restituisce sempre 0 dopo il primo timeout
Il codice è illustrato di seguito.
static const int maxLog = 10000;
int main()
{
int servSock;
signal(SIGPIPE, SIG_IGN);
if((servSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket create fail\n");
exit(-1);
}
int val = 1;
if(setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))<0)
{
DieWithUserMessage("setsockopt error");
}
struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(22000);
if(bind(servSock, (struct sockaddr *) &serverAddr,
sizeof(serverAddr)) < 0)
{
printf("socket bind fail\n");
exit(-1);
}
if(listen(servSock, maxLog) < 0)
{
printf("listen failed\n");
exit(-1);
}
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(servSock, &read_set);
int maxfd1 = servSock + 1;
std::set<int> fd_readset;
for(;;){
struct timeval tv;
tv.tv_sec = 5;
int ret = select(maxfd1, &read_set, NULL, NULL, tv);
if(ret == 0)
continue;
if(ret < 0)
DieWithUserMessage("select error");
if(FD_ISSET(servSock, &read_set))
{
struct sockaddr_in clntAddr;
socklen_t clntAddrlen = sizeof(clntAddr);
int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrlen);
if(clntSock < 0)
{
printf("accept failed()");
exit(-1);
}
maxfd1 = 1 + (servSock>=clntSock? servSock:clntSock);
FD_SET(clntSock, &read_set);
fd_readset.insert(clntSock);
}
}
}
consiglio generale: utilizzare sondaggio() anziché selezionare(). – Dummy00001
Devi usare '& tv' invece di' tv' in 'select' –