Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// [...] timeval time; time.tv_sec = 0; time.tv_usec = 1; // select() ret = select(0, &m_fdSetRead, NULL, NULL, &time); if(ret < 1) return 1; Client newConnection; for(x = 0; x < m_fdSetRead.fd_count; x++) { int addrsize = sizeof(SOCKADDR_IN); int freeClientSlot; if(m_fdSetRead.fd_array[x] == m_acceptSocket) { newConnection.socket = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize); freeClientSlot = getFreeClientSlot(); if(freeClientSlot == -1) continue; m_Client[freeClientSlot] = newConnection; m_Client[freeClientSlot].used = true; } } // [...] |
C-/C++-Quelltext |
|
1 |
if (FD_ISSET (m_acceptSocket, &m_fdSetRead)) { [...] } |
C-/C++-Quelltext |
|
1 2 3 |
FD_ZERO (&m_fdSetRead); // Alles muss raus! FD_SET (m_acceptSocket, &m_fdSetRead); // Auf den will ich hören. res = select (...); // gibts was? |
Zitat von »"rklaffehn"«
Benutzt du auch die FD_XXX Macros, um Socket-Deskriptoren im m_fdSetRead zu setzen/prüfen (bin halt POSIX verseucht )? Mitkannst du deine inneres Schleife abkürzen.
C-/C++-Quelltext
1 if (FD_ISSET (m_acceptSocket, &m_fdSetRead)) { [...] }
Das utopische Verhalten könnte daran liegen, dass du m_fdSetRead vor dem ::select aufruf nicht neu initialisierst. Das ist wichtig, weil ::select in diese Mengen modifiziert.
C-/C++-Quelltext
1 2 3 FD_ZERO (&m_fdSetRead); // Alles muss raus! FD_SET (m_acceptSocket, &m_fdSetRead); // Auf den will ich hören. res = select (...); // gibts was?
Zitat von »"rklaffehn"«
Mir ist ohnehin nicht klar, warum die Deskriptormenge eine Mitgliedsvariable deiner Klassen ist/sein muss.
Zitat von »"rklaffehn"«
Du arbeitest mit einem Timeout. Wenn an keinem Socket was ankommt, ist das ::select Ergebnis 0, was < 1 ist. Für deinen Fall behandelst du das als Fehler (glaub ich). Echte Fehler sind aber < 0.
Zitat von »"rklaffehn"«
Wenn dein m_acceptSocket im "listen" Zustand ist (du hast, irgendwann mal ::listen drauf aufgerufen), dann will sich immer jemand verbinden, wenn auf m_acceptSocket Daten zu lesen sind. ::accept erzeugt dir ja einen neuen Socket, auf dem die weitere Kommunikation für die neue Verbindung läuft. Damit stellt sich deine zweite Frage nicht wirklich.
C-/C++-Quelltext |
|
1 |
WSAAsyncSelect |
C-/C++-Quelltext |
|
1 |
::listen (m_acceptSocket, 1); // m_acceptSocket soll max. Verbindungen gleichzeitig akzeptieren |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
bool TcpIpServer::listen () { if (-1 != _socket) return false; // erzeugen _socket = ::socket (PF_INET, SOCK_STREAM, 0); if (_socket < 0) { dumpError ("create", errno); return false; } // Non-Blocking machen int flags = ::fcntl (_socket, F_GETFL, 0); if ( flags < 0 || ::fcntl (_socket, F_SETFL, flags | O_NONBLOCK) < 0) { dumpError ("F_SETFL", errno); close (); return false; } // Adresse definieren, auf der zugehört wird struct sockaddr_in sock_addr; ::memset (&sock_addr, 0, sizeof (sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_port = htons (32410); sock_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); if (::bind (_socket, reinterpret_cast<const struct sockaddr*> (&sock_addr), sizeof (sock_addr)) < 0) { dumpError ("bind", errno); return close (); } // Sagen, dass man Verbindungen hören will. if (::listen (_socket, 1) < 0) { dumpError ("listen", errno); close (); return false; } return true; } |
C-/C++-Quelltext |
|
1 2 3 4 5 |
int incoming_socket = ::accept (_socket); if (incoming_socket < 0 && errno != EWOULDBOCK && errno != EAGAIN) { return false; } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
TIMEVAL time = { 3, 0 }; fd_set readset, errorset; while(server->status == READY) { FD_ZERO(&readset); FD_ZERO(&errorset); FD_SET(server->Socket, &readset); FD_SET(server->Socket, &errorset); for(std::list<BasicServerClient*>::iterator temp = server->ClientList.begin(true); temp != server->ClientList.end(); temp++) { if((*temp)->status == READY) FD_SET((*temp)->Socket, &readset); } server->ClientList.unlock(); if(SOCKET_ERROR == select(NULL, &readset, NULL, &errorset, &time)) { server->geterror();//EDIT: muss mitgelogt werden! } for(std::list<BasicServerClient*>::iterator temp = server->ClientList.begin(true); temp != server->ClientList.end(); temp++) { if(((*temp)->status == READY) && FD_ISSET((*temp)->Socket, &readset)) (*temp)->ClientCallback(); } server->ClientList.unlock(); } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Client newConnection; for(x = 0; x < m_fdSetRead.fd_count; x++) { int addrsize = sizeof(SOCKADDR_IN); int freeClientSlot; if(m_fdSetRead.fd_array[x] == m_acceptSocket) { newConnection.socket = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize); freeClientSlot = getFreeClientSlot(); if(freeClientSlot == -1) continue; m_Client[freeClientSlot] = newConnection; m_Client[freeClientSlot].used = true; } } |
C-/C++-Quelltext |
|
1 2 |
// siehe oben.. if(m_fdSetRead.fd_array[x] == m_acceptSocket) |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
TIMEVAL time = { 3, 0 }; fd_set readset, errorset; while(!quit) { FD_ZERO(&readset); FD_ZERO(&errorset); FD_SET(m_acceptSocket, &readset); FD_SET(m_acceptSocket, &errorset); for(std::list<Client*>::iterator temp = ClientList.begin(); temp != ClientList.end(); ++temp) FD_SET((*temp)->Socket, &readset); if(SOCKET_ERROR == select(NULL, &readset, NULL, &errorset, &time)) { //EDIT: muss mitgelogt werden! } if(FD_ISSET(m_acceptSocket, &readset)) { newConnection.socket = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize); freeClientSlot = getFreeClientSlot(); if(freeClientSlot != -1) { m_Client[freeClientSlot] = newConnection; m_Client[freeClientSlot].used = true; } } for(std::list<Client*>::iterator temp = ClientList.begin(); temp != ClientList.end(); ++temp) { if(FD_ISSET((*temp)->Socket, &readset)) ;//mach was intelligentes } } |
Zitat von »"$nooc"«
mein code basiert auf einem tutorial.. ich versteh zb. auch nicht was mit dieser if() bedingung erreicht wird O_o
C-/C++-Quelltext
1 2 // siehe oben.. if(m_fdSetRead.fd_array[x] == m_acceptSocket)
C-/C++-Quelltext |
|
1 |
if (FD_ISSET (m_acceptSocket, &m_fdSetRead)) { ... } |
C-/C++-Quelltext |
|
1 2 |
u_long set_nonblocking = 1; ioctlsocket (m_acceptSocket, FIONBIO, &set_nonblocking); |
Zitat von »"rklaffehn"«
Wenn man mit select "nonblocking" simulieren will, darf man kein Timeout benutzen (Parameter NULL), damit select nicht blockiert.
Werbeanzeige