Lesesocket: EAGAIN: Ressource vorübergehend nicht verfügbar
Ich habe einen Socket in C ++ erstellt und brauchte ihn, um ein bestimmtes Zeitlimit für die Verbindung zu haben. Das ist also was passiert:
Socket erstellenMachen Sie es NON_BLOCKINGAnruf verbindenEs gibt -1 zurück und errno EINPROGRESS wie erwartetAnruf auswählenGibt> 0 zurück, sodass die Verbindung hergestellt wurdeStellen Sie die Steckdose wieder auf BLOCKINGCode für diesen Teil ist der folgende:
<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>
Das funktioniert ok Aber dann habe ich eine Schleife, in der ich eine Funktion aufrufe, die prüft, ob ein neues Paket zum Lesen empfangen wurde:
<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>
Die Lesefunktion gibt EAGAIN als errno aus, was bedeutet, dass die Ressource vorübergehend nicht verfügbar ist. Dann nehme ich an, dass ich nicht verbunden bin, und da boolean connected jetzt false ist, werde ich in der Schleife versuchen, die Socket-Verbindung erneut herzustellen, und so weiter.
Erstens weiß ich nicht, warum ich diesen Fehler erhalte.
Zweitens weiß ich nicht, ob ich überhaupt nicht verbunden bin, oder ich bin derjenige, der die Verbindung trennt, wenn der neue Socket nach diesem Fehler erstellt wird.
Irgendeine Hilfe?