Jostain syystä seuraavassa koodissa tuo ohjelman suoritus ei koskaan pääse tuosta select-funktion kohdasta eteenpäin, vaikka yritän connectata clientillä.
Seuraava koodi on siis peräisin serveristä:
fd_set set; FD_ZERO(&set); FD_SET(m_socket, &set); SOCKET AcceptSocket; while(1) { cout << "selectlooop" << endl; timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; if(select(m_socket + 1, &set, NULL, NULL, &tv) > 0) { cout<<"taalla ollaan" << endl; if(FD_ISSET(m_socket, &set)) { AcceptSocket = accept(m_socket, NULL, NULL); m_socket = AcceptSocket; break; } break; } }
Miksi select-funktio ei koskaan onnistu, vaikka yritän clientillä connectata siihen? Missä meni vikaan..?
Määrität tuossa odotusajaksi sekuntin, mahtaako olla riittävästi? Lisää siihen if-lauseeseen vaikka "else cout << "Ei ehtinyt!" << endl;
"
Jos muuten käytät WinSock 2:ta, niin tuo select-funktion ensimmäinen parametri on turha.
Ja C-kooditagin käyttö olisi suositeltavaa. [ koodic] - [/koodic ]
No mitäs tolla odotusajalla on tossa väliä kun se pyörii tossa while(1) silmukassa niin kauan kuin joku ottaa yhteyttä.. Eikös sen pitäis kokeilla tota selectiä aina uudestaan jos kukaan ei ottanu yhteyttä ton sekunnin aikana?
No eikö homma toimi niin, että se kokeilee yhtä selectia, jos se ei saa dataa, se sekunnin päästä kokeilee toisen. Jos taas vastauksen saamiseen meneekin 1,1 sekuntia, homma ei toimi, koska se vastaus ei vastaa siihen toiseen menossaolevaan selectiin?
Vähän sekavasti selitetty, mutta tajunnet pointtini. Ja en tosiaan tiedä asiasta mitään, mutta näin järkeilisin.
Otapa eteesi MSDN:n Getting Started with Winsock ja mieti sen kanssa. Kun ei ole koko koodia edessä, niin ei voi sanoa, oletko tehnyt virheen jossakin aiemmin, mutta sitä voisi veikata.
Arvaa vaan kuinka monta kertaa oon ton MSDN:n kanssa tota miettiny mutta sieltä ei oikein löydy tosta selectistä mitään esimerkkiä. Selectiä käytän kun yritän tehdä ohjelmasta ei-blokkaavan.
MSDN kirjoitti:
The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
- -
The select function returns the total number of socket handles that are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.
Eli niin kauan, kuin tuo set
ei sisällä sockettia, johon voisi kirjoittaa, select(...) > 0 ei toteudu, ja ilmeisesti otat yhteyden vasta looppin sisällä... Näin minä sen ainakin ymmärrän, mutta en ole WinSockia käyttänyt, joten...
Ratkaisu:
MSDN kirjoitti:
The accept function can block the caller until a connection is present if no pending connections are present on the queue, and the socket is marked as blocking. If the socket is marked as nonblocking and no pending connections are present on the queue, accept returns an error as described in the following.
Voit siis käyttää ihan huoletta acceptia kunhan lisäät socketin luonnin jälkeen tällaisen:
u_long State = 1; // Joku muu kuin nolla ioctlsocket(m_socket, FIONBIO, &State); // Tehdään socketista ei-blokkaava.
Tämän jälkeen accept palauttaa heti arvon INVALID_SOCKET
, jos yhteyspyyntö ei ole jo odottamassa.
Edit: typoja...
Aihe on jo aika vanha, joten et voi enää vastata siihen.