Soquete de leitura: EAGAIN: Recurso temporariamente indisponível
Eu criei um soquete em C + + e eu precisava ter algum tempo limite de conexão. Então é isso que está acontecendo:
Criar soqueteTornar NON_BLOCKINGLigação conectadaEle retorna -1 e errno EINPROGRESS conforme o esperadoLigue para selecionarRetorna> 0, então a conexão foi feitaFaça o soquete BLOQUEAR novamenteO código desta parte é o seguinte:
<code>bool mastControl::prepareSocket(char * address, int port, int * sockfd) { struct sockaddr_in serv_addr; struct timeval timeout = {0,100000}; struct timeval connTimeout; struct hostent * server = NULL; fd_set socketSet; socklen_t lon; int sockOpt = 0; long socketFlags = 0; int buffersize = 8; int res = 0; int connectReturn = 0; const int WAIT_TO_RECONN = 15; server = gethostbyname(address); *sockfd = socket(AF_INET, SOCK_STREAM, 0); if (*sockfd < 0) { qDebug()<<"Impossible to open socket: "<<strerror(errno); return false; } if (server == NULL) { qDebug()<<"No such host: "<<strerror(h_errno); return false; } // Initializating server direction struct: bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(port); // Making socked non-blocking in order to set a timeout value for connection: if((socketFlags = fcntl(*sockfd, F_GETFL, NULL)) < 0){ qDebug()<<"Impossible to retrieve sockets descriptor flags "<<strerror(errno); return false; } socketFlags |= O_NONBLOCK; if(fcntl(*sockfd, F_SETFL, socketFlags) <0){ qDebug()<<"Impossible to update sockets descriptor flags: "<<strerror(errno); return false; } connectReturn = connect(*sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)); if(connectReturn < 0){ if(errno == EINPROGRESS){ do{ // Establishing a 15 seconds timeout: connTimeout.tv_sec = 15; connTimeout.tv_usec = 0; FD_ZERO(&socketSet); // Initialising set of sockets as an empty set FD_SET(*sockfd, &socketSet); // Adding socket to set connectReturn = select(*sockfd+1, NULL, &socketSet, NULL, &connTimeout); if(connectReturn<0 && errno!=EINTR){ // Error in select qDebug()<<"Connection error in select function: "<<strerror(errno); return false; } else if(connectReturn>0){ // Socket selected for writing lon = sizeof(int); if(getsockopt(*sockfd, SOL_SOCKET, SO_ERROR, (void*)(&sockOpt), &lon) <0){ qDebug()<<"Unnable to get socket options: "<<strerror(errno); return false; } // Checking the value returned: if(sockOpt){ qDebug()<<"Error in delayed connection: "<<strerror(errno); return false; } break; } else{ // Timeout qDebug()<<"Connection timeout exceeded: "<<strerror(errno); return false; } } while (1); } else{ qDebug()<<"Connection error: "<<strerror(errno); sleep(WAIT_TO_RECONN); // Wait 15 seconds return false; } } //Connected // Must set the socket as blocking again: if((socketFlags = fcntl(*sockfd, F_GETFL, NULL)) < 0){ qDebug()<<"Impossible to retrieve sockets descriptor flags "<<strerror(errno); return false; } socketFlags &= (~O_NONBLOCK); if(fcntl(*sockfd, F_SETFL, socketFlags) <0){ qDebug()<<"Impossible to update sockets descriptor flags "<<strerror(errno); return false; } if (setsockopt (*sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { qDebug()<< "ERR - setsockopt failed"; return false; } if (setsockopt (*sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { qDebug()<< "ERR - setsockopt failed"; return false; } if ((res = setsockopt (*sockfd, SOL_SOCKET, SO_SNDBUF, &buffersize, sizeof(buffersize))) == -1) { qDebug()<< "ERR - setsockopt failed (SO_SNDBUF) = " << res; return false; } //Socket Ready return true; } </code>
Isso funciona bem. Mas então eu tenho um loop onde eu estou chamando uma função que verifica se há um novo pacote recebido para ler:
<code>bool mastControl::findPacket(int sockfd, st_messageMastToPc * messageReceived, bool * connected) { int n = 0; bool messageFound = false; char * buffer = (char *) messageReceived; unsigned int pos = 0; while ( ((n = read(sockfd, &(buffer[pos]), 1)) > 0) and not messageFound) { //qDebug() << "read output " << n; if (n == 1) { pos++; if ( (pos == 1) && (buffer[0] == 2)) { // Some stuff... } else if ( (pos == 2) && (buffer[1] == 2) ) { // Some stuff... } else if (pos >= uiMessageMastToPcSize) { messageFound = true; //Complete message received } else if (pos < 2) { // Reseting pos pos = 0; } } } if (n < 0){ qDebug()<< "Disconnected. Reason #" << errno << ": " << strerror(errno); *connected = false; } return messageFound; } </code>
A função de leitura está fornecendo EAGAIN como errno, que significa "Recurso temporariamente indisponível". Então, suponho que estou desconectado e, como o booleano conectado agora é falso, no loop, estarei tentando reconectar a criação do soquete novamente, e assim por diante.
Então, em primeiro lugar, não sei porque estou recebendo este erro.
Em segundo lugar, não sei se estou desconectado, ou sou eu quem está desconectando ao criar o novo soquete após esse erro.
Qualquer ajuda?