🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

send() and recv() blocking w/ threads

Started by
10 comments, last by MadProgrammer 22 years, 7 months ago
all my sockets are blocking. i have a thread recvThread. it just sits in a recv() call, waiting for some data. meanwhile, i wana send something to the same socket. will that work?
Advertisement
You''d better wait in a select() call.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
please elaborate
i think i understand wut you are saying.
wut if i dont wana wait? then do i just hafta make my sockets non-blocking and get on w/ life?
What you have is a thread polling the sockets. In such a case, it is perfectly ok to have it block while there is no IO on the sockets. That''s what select() does, allowing you to handle several socket at once.

If you make them non-blocking, say, by telling select() to return immediately, then you are spending CPU time constantly going through the poll loop.

In such a case, it may be counter-productive to have the poll loop in a separate thread, though the system calls should ensure that it gets switched out.

You might (I said MIGHT) finally consider asynchronous IO, where the operating system notifies the application that IO occurred, instead of having the application constantly check. But that''s another story altogether.

Conclusion : with several threads, blocking is the right solution. And select() is designed to handle multiplexing.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
how do i use select()? the only place ive seen it is the AsyncSelect, and i dont wana do that again.

from what ive heard rumors of in tutorials, i can use select() to determine if there''s nething in the recv() queue. thats what i wana do. how?

also, if select() blocks, it needs to be in its own thread...therefore, how do i know if i''m currently receiving on the thread when i wana do a send() in a different thread? send() doesnt work when u are recv()ing, so i gotta get around that



thanks much!
select() can be found in winsock2.h
In the doc:
Platform SDK->Networking and Distributed Services->Windows Socket 2->Reference->Functions->select

It works as follow :

    void pollsockets(){  fd_set recv_ready;   // set for which recv() won't block  fd_set send_ready;   // set for which send() won't block  // The sets are actually sets of file descriptors  // they can be real files, or sockets, or pipes ...  FD_ZERO( &recv_ready ); // clears the set  FD_ZERO( &send_ready ); // idem  // Add the server socket to the set of sockets we want   // to check for recv (i.e. accept() )  FD_SET( listening_socket, &recv_ready );   // Add all other sockets to both recv and send sets.  // socket_array is an array of SOCKET descriptors,  // the kind returned by socket() or accept().  int i;  for( i = 0; i < number_of_sockets; ++i )  {    FD_SET( socket_array[i], &recv_ready );     FD_SET( socket_array[i], &send_ready );   }  // First parameter is ignored by Windows  // Second, sockets checked for possible read  // Third, sockets checked for possible write  // Fourth, sockets checked for error (NULL = no check)  // Fifth, timeout (NULL = blocking)  int status = select( NULL, &recv_ready, &send_ready, NULL, NULL );  // select will zero out in the set the entries for which  // the corresponding test fails. It will not return until   // it either times out (here, never), or one of the sets   // is non empty. In which case those entries are guaranteed  // not to block on the corresponding call.  // Check for a new connection  if ( FD_ISSET( listening_socket, &recv_set ) )    HandleNewConnection(); // your function here, I'm lazy.  // Check if there is something to be read  for( i = 0; i < number_of_sockets; ++i )    if ( FD_ISSET( socket_array[i], &recv_set ) )       ReadDataFromSocket( i ); // Still lazy  // Check if we can write something  for( i = 0; i < number_of_sockets; ++i )    if ( FD_ISSET( socket_array[i], &recv_set ) )       WriteDataToSocket( i ); // Still lazy}    


Of course, you still have to write HandleNewConnection (easy enough), ReadDataFromSocket and WriteDataToSocket (much more painful).


Edited by - Fruny on November 24, 2001 9:13:15 PM
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
thanks much (again)
Keep in mind that I typed that from memory... beware the bugs
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
no prob. thanx much. i''d never really heard of using select in this way.

This topic is closed to new replies.

Advertisement