Beschäftige mich grad mit Netzwerkprogrammierung in C/C++...
Bin jetzt aber auf folgendes Problem gestoßen:
Mal grob der Ablauf:
select wartet auf neue Connections:
int nready = ::select( m_highestsock+1, &m_currentsockset, NULL, NULL, &tv );
Neue Connection kommt an, nready wird auf 1 gesetzt, über accept einem Deskriptor zugewiesen und nready dekrementiere ich danach für weitere Verarbeitung...
Im nächsten Durchlauf wird nready allerdings vom select(...) wieder auf 1 gesetzt, obwohl keine neue Verbindung ankommt und obwohl auf diesem Deskriptor keinerlei Daten liegen...
Auf jeglichen Seiten im I-Net lese ich allerdings, dass select nur neue Verbindungen oder lesbare Deskriptoren MIT Daten zurückliefert. Es existieren sogar Funktionen, die select(...) dazu benutzen um bei einem Deskriptor darauf zu warten, dass Daten lesbar werden, damit recv bzw. recvfrom nicht blockieren - interessanterweise tun sie das bei mir allerdings auch nicht...
Jemand ne Idee? Benutze ein FreeBSD 5.3 falls das hilft...
Wenn jemand mehr Info braucht, hier mal die Klassenfunktion:
Das Problem ist, dass die Funktion wunderbar wartet solange keine Connections aufgebaut werden...
Sobald eine Verbindung mit einem Client besteht, rennt der select(...) durch weil er angeblich lesbar ist - das heisst im Prinzip hab ich dann keinen schlafenden Prozess mehr, sondern einen der ständig am rödeln ist... und das ist alles andere als brauchbar
Über fcntl(...) den einzelnen fd auf ~O_NONBLOCK zu setzen hab ich auch versucht, keine Wirkung...
Jetzt bin ich ein wenig irritiert
P.S.: Und sorry, das Board wirft irgendwie die Formatierung vom Code ein wenig durcheinander
Bin jetzt aber auf folgendes Problem gestoßen:
Mal grob der Ablauf:
select wartet auf neue Connections:
int nready = ::select( m_highestsock+1, &m_currentsockset, NULL, NULL, &tv );
Neue Connection kommt an, nready wird auf 1 gesetzt, über accept einem Deskriptor zugewiesen und nready dekrementiere ich danach für weitere Verarbeitung...
Im nächsten Durchlauf wird nready allerdings vom select(...) wieder auf 1 gesetzt, obwohl keine neue Verbindung ankommt und obwohl auf diesem Deskriptor keinerlei Daten liegen...
Auf jeglichen Seiten im I-Net lese ich allerdings, dass select nur neue Verbindungen oder lesbare Deskriptoren MIT Daten zurückliefert. Es existieren sogar Funktionen, die select(...) dazu benutzen um bei einem Deskriptor darauf zu warten, dass Daten lesbar werden, damit recv bzw. recvfrom nicht blockieren - interessanterweise tun sie das bei mir allerdings auch nicht...
Jemand ne Idee? Benutze ein FreeBSD 5.3 falls das hilft...
Wenn jemand mehr Info braucht, hier mal die Klassenfunktion:
Code:
int NetSocket::select() {
struct timeval tv;
fd_set m_currentsockset;
tv.tv_sec = 2;
tv.tv_usec = 0;
m_currentsockset = m_sockset;
cout << "waiting for incoming connections..." << endl;
int nready = ::select( m_highestsock+1, &m_currentsockset, NULL, NULL, &tv );
//too many connections?
if (m_sockclient.size() < FD_SETSIZE) {
// new connection
if (FD_ISSET(m_socklisten, &m_currentsockset)) {
int clilen = sizeof( m_addrclient );
int connfd = ::accept( m_socklisten, ( sockaddr * ) &m_addrclient, ( socklen_t * ) &clilen );
cout << "new connection accepted on " << connfd << endl;
m_sockclient.push_back(connfd);
FD_SET(connfd, &m_sockset); /* add new descriptor to set */
test = connfd;
if (connfd > m_highestsock)
m_highestsock = connfd; /* for select */
nready--;
OnNewConnection( m_sockclient.size() );
}
}
//check all connections for data
if (nready > 0) {
int sockfd;
vector<int>::iterator it;
for( it = m_sockclient.begin(); it != m_sockclient.end(); it++ ) {
if ( (sockfd = *it) < 0)
continue;
if (FD_ISSET(sockfd, &m_currentsockset)) {
if (NetSocket::is_readable(sockfd,0,5)) {
cout << "data available on " << sockfd << endl;
OnNewData(sockfd);
nready--;
}
}
}
}
cout << "nready at " << nready << endl << endl;
return nready;
}
Das Problem ist, dass die Funktion wunderbar wartet solange keine Connections aufgebaut werden...
Sobald eine Verbindung mit einem Client besteht, rennt der select(...) durch weil er angeblich lesbar ist - das heisst im Prinzip hab ich dann keinen schlafenden Prozess mehr, sondern einen der ständig am rödeln ist... und das ist alles andere als brauchbar
Über fcntl(...) den einzelnen fd auf ~O_NONBLOCK zu setzen hab ich auch versucht, keine Wirkung...
Jetzt bin ich ein wenig irritiert
P.S.: Und sorry, das Board wirft irgendwie die Formatierung vom Code ein wenig durcheinander