Jump to content
  • Advertisement
Sign in to follow this  

Help, non-blocking sockets.

This topic is 3392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello there :) I'm having lots of trouble making a non-blocking winsock program(win32 console application.) I have a little project that is working(blocking mode.) I would be glad if you could have a look and see if you can give me a hint, tips och anything to point me in the right direction. Project download link: http://thuski.se/ixuz/projekt/winsock.rar My goal is to make a fun multiplayer iceclimbers game before 11-03-2009 for a lan event. Feel free to check out the website too http://www.ntilan.se/ Thanks! // ixuz

Share this post


Link to post
Share on other sites
Advertisement
I have not looked at your code, but I might give you some advice anyways.
I suggest that you use 2 threads when using sockets. 1 listening thread, and 1 sending thread.
Add items you want to send in a Send queue, and let the sender thread send items from that queue.
Same goes for the listening thread.
Remember to properly lock the send/receive queue's when adding/removing items from them.


Share this post


Link to post
Share on other sites
I am in the process of creating a Winsock tutorial site.

I have actually covered a tutorial non-blocking sockets on my programming site (both client and server). You are welcome to take a look. Feel free to comment and critique. :)

www.win32developer.com

Share this post


Link to post
Share on other sites
I've acually succeded in make a non-blocking server and a non-blocking client now yay. But now another problem pops up, I can't get more than one client connected at the same time. How do you store multiple clients? I've been thinking of something like this, accepting a client then store it in a vector for later use.

If you'd like to have a look at my source code you can find it here:
http://thuski.se/ixuz/projekt/winsock2.rar

Thanks // ixuz

Share this post


Link to post
Share on other sites
Quote:
Original post by ixuz
I've acually succeded in make a non-blocking server and a non-blocking client now yay. But now another problem pops up, I can't get more than one client connected at the same time. How do you store multiple clients? I've been thinking of something like this, accepting a client then store it in a vector for later use.
Yup, exactly.

Share this post


Link to post
Share on other sites
Yay, it worked out really nice! I can wait for two clients to connect to the server, they both can send/recv from the server(non-blocking). :)

How can I accept connecting clients while my server is running, I have done it like this for now:
Quote:

void ServerSocket::StartHosting( int port )
{
Bind( port );
Listen(); // blocking and awaiting client
Listen(); // blocking and awaiting client again
}

void ServerSocket::Listen() {
//cout << "LISTEN FOR CLIENT..." << endl;
listen ( mySocket, 2 );

acceptSocket = accept( myBackup, NULL, NULL );
while ( acceptSocket == SOCKET_ERROR )
{
acceptSocket = accept( myBackup, NULL, NULL );
}
mySocket = acceptSocket;

unsigned long a[1];
ioctlsocket(mySocket, FIONBIO, a);
acceptedSockets.push_back( mySocket );

cout << "CONNECTION ACCEPTED" << endl;
}

The program will wait for exact two clients to connect then it continues.

How can I make my accepting function work calling without blocking mode?
Would it work to call the accept function every frame to possibly accept new clients?
Am I supposed to call the select() function before accept() function? if so how do I use select() properly? :)

Thanks // ixuz :D

[Edited by - ixuz on January 23, 2009 1:49:53 PM]

Share this post


Link to post
Share on other sites
Quote:
Would it work to call the accept function every frame to possibly accept new clients?


Yes.

Regarding select(): You EITHER use non-blocking sockets, OR select, not both.

With select(), you send in a set of sockets. Select will tell you which of those sockets you can receive on, or send on, without blocking.

After select(), you walk the set that comes back, and call recv() or send() on those sockets, once each. Because they came back from select() as available, it is guaranteed that your call will not block for the first call to each socket. Of course, there may not be as much data as you want there -- recv() may return just one byte, or send() may be able to send just one byte -- but you are guaranteed to make progress.

Share this post


Link to post
Share on other sites
Don't believe hplus0603. You need to use non-blocking sockets when you use i/o multiplexing (select, poll, epoll ...). Otherwise it can happen that recv/send blocks.

Share this post


Link to post
Share on other sites
Quote:
Original post by imgty

Otherwise it can happen that recv/send blocks.


If properly implemented, this should not happen.

Quote:
For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available—up to the size of the buffer specified


It will block only if there is no data available in the buffer. select() determines which sockets have at least some data available. But the important thing is to call send/recv/accept only once per select() call, and only on descriptors returned in corresponding set.

Share this post


Link to post
Share on other sites
Ok, for recv on a tcp socket that might never happen. On a UDP socket a packet could be dropped theoretically between the call to select and the receive function.

But...
send on a socket in blocking mode blocks until the *whole* buffer has been consumed. At least on Windows. It might be different on other operating systems.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!