-
recv() blocks
I recently asked about multithreading - thanks for you help and I ordered a book for more information.
Now I have been working on my client-server architecture for a small chat relay. Well I have it working a lil bit. My problem is that once I invoke the recv() function code processing halts there and waits for inbound data. I would rather it work like the _kbhit() function does – checking for inbound data that is waiting in some sort of buffer. If there is none then move onto the next statement. If there is then process it how it has to be.
I have looked at some msdn articles using winsock2 – but my word are they ever confusing haha. I apologize if this is a bad post – let me know of my effort level – haha :-p
Umm.... I looked into recvfrom as someone said it wont halt processing (or I guess the term is "blocking") but that really didnt work for me :-\.
Again thank you for all your help!! :-D
-
There are a couple methods depending on platform. The most stright forward (IMO) approach is poll the socket to see if data is avialable. If it is you call recv() if not you continue on. To do this use select().
-
Ok I have done a whole ton of research and I made a little headway. Now the only problem is that it will not receive data. Here is my code. Keep in mind count is initialized to {0,0} and I tried other values.
Code:
while(recent != 'x')
{
if(_kbhit())
{
kbhit = _getch();
send(m_socket, &kbhit, 1, 0);
}
if(select(0, &ReadFDs, 0, 0, &count) > 0)
{
if(FD_ISSET(m_socket, &ReadFDs))
{
bytesRecv = recv( m_socket, &recent, 1, 0 );
cout << "Bytes Received: " << bytesRecv << " Data: " << recent << endl;
}
}
}
|: REVISION
Alright well I fixed my problem - now I have this..
Code:
while(recent != 'x')
{
if(_kbhit())
{
kbhit = _getch();
send(m_socket, &kbhit, 1, 0);
}
FD_SET(m_socket, &ReadFDs);
if(select(0, &ReadFDs, 0, 0, &count) > 0)
{
if(FD_ISSET(m_socket, &ReadFDs))
{
bytesRecv = recv( m_socket, &recent, 1, 0 );
cout << "Bytes Received: " << bytesRecv << " Data: " << recent << endl;
}
}
}
But is it really necessary to use FD_SET every loop? Why does it act as such - or is that the requirement?
-
> But is it really necessary to use FD_SET every loop?
Yes, select() modifies the set so you can tell which fd's have changed and which haven't with FD_ISSET().
If you have a lot of fd's to watch for, then you can keep a master set which only changes when fd's are created and destroyed.
Code:
ReadFDs = MasterFDs;
if(select(0, &ReadFDs, 0, 0, &count) > 0)
-
Ohh ok - I was under the impression that select() updated the values - even if they were zero and this in effect would not need the FD_SET().
Thank you for your help. :-)
-
If you're writing just for Windows, I wouldn't go with select() personally - it's rather archaic (all those macros).
As for what *to* use, it depends on how you want your system to scale. You say "small chat relay", so you're probably not wanting to support 100s->1000s of concurrent clients? In that case, maybe use WSAAsyncSelect (Windows message based) notification, which is pretty easy to use and fits right into your Windows app.
-
well right now no - not the 100s and 1000s - but maybe in the future... hehe