Jump to content
  • Advertisement
Sign in to follow this  
Crazyfool

Winsock C++ Connect()

This topic is 3614 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

Hey, I have had this problem for a while and not quite sure how to fix it. If my game tries to connect to my game server that is offline, it will take between 15-20 seconds to timeout. Basically, I want to know how to make it timeout after 3-5 seconds. I googled around and basically it seems that it should be 3 seconds, or at least 3 seconds per attempt (3 for first. 6 for second, etc). Does this mean that one connect call is making multiple attempts and thus causing a long delay? I am using non-blocking sockets and here is a chunk of code: EDIT 1: Actually, I dont make the socket non-blocking till after the call. Is this something that will affect it? EDIT 2: changing it to nonblocking simply does not allow connection. when server is up or down it instantly returns "failed to connect" error message (this is a message I made, so its not any wsaerror or anything) EDIT 3: On further inspection, all calls made by connect() return SOCKET_ERROR, but my server registers the connect. I add a check to see if the error is WSAWOULDBLOCK and when it is, I reconnect after sleep()ing, which returns a SOCKET_ERROR of "WSAEISCONN" This is strange..
       if(WSAStartup(0x0202, &wsa))
	{
		connected = false;
		return -1;
	}
	if(wsa.wVersion != 0x0202)
	{
		WSACleanup();
		connected = false;
		return -1;
	}

	s = socket(AF_INET, SOCK_STREAM, 0);

	target.sin_family = AF_INET;
	target.sin_port = htons(6009);

	target.sin_addr.s_addr = inet_addr(SERV_IP);

	int error = connect(s, (LPSOCKADDR)&target, sizeof(target));
	if(error == SOCKET_ERROR)
	{
		connected = false;
		return -1;
	}




Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Crazyfool
EDIT 2: changing it to nonblocking simply does not allow connection. when server is up or down it instantly returns "failed to connect" error message (this is a message I made, so its not any wsaerror or anything)


Right. If the socket is non-blocking, connect will always return SOCKET_ERROR, and WSAGetLastError will be WSAEWOULDBLOCK. You can then use select, WSAAyncSelect or WSAEventSelect as appropriate to wait for the connect to succeed.

I would suggest that 3 seconds is probably a bit short, however. 5-10 seconds is probably better, even on a LAN.

Share this post


Link to post
Share on other sites
I had a 3rd edit, basically should I test to see if socket_error is: WSAEISCONN to see if it worked right?

edit: and thanks for your help thus far.


Im not quite sure how select works; I thought it was for recving data on multiple sockets.

Share this post


Link to post
Share on other sites
Quote:
Original post by Crazyfool
I add a check to see if the error is WSAWOULDBLOCK and when it is, I reconnect after sleep()ing


The problem is that now all connections will take 3 seconds.

If you're going to use non-blocking sockets, you need to learn how to use them properly, and that means using one of the functions I listed in my previous response.

WSAAsyncSelect works well for an application with a user-interfcae (since it's based on Windows messags). WSAEventSelect is better if you're not displaying a user-interface (or you need something more efficient than windows messages).

You can also do it using I/O completion ports for the ultimate in efficiency, but that's probably a bit advanced at this stage...

Share this post


Link to post
Share on other sites
I appreciate that, I guess I'll look into them more.

The thing is, I have been using non blocking socket for connects which has been working fine, and then changing it to non-blocking (not sure why, thats how I learned).

I just wanted to improve on the fact that things can go wrong, server crashes and players dont know about it - I dont want anyone to think their computer froze up because its taking 20ish seconds.


While I look into the three functions you listed, I would like to ask something. Is there something wrong with doing this but calling connect several times (lets say, enough to reach 5 seconds, so using a timer and a while loop) and checking if the error ever is "WSAEISCONN"?

Furthermore, should I be using select() or one of the two other methods for all my client and possibly even server calls? If so, is there a place I can find information on why? (I have skimmed beej's and a few other places and it seems on the surface its to be more efficient with the CPU, you get the benefits of non-blocking speed of call but also the benefit of non-blocking sockets in that it doesnt use a lot of the CPU)

Thanks again

Share this post


Link to post
Share on other sites
If you call connect() on a socket that is already connecting, then that may reset your current connection attempt and re-start a new attempt. That may, in turn, cause the connection to never actually complete. I don't know which of the current IP stacks have that behavior; if you're interested you can try them all and see :-)

Share this post


Link to post
Share on other sites
Thanks for more insight, always good to get information - any information - from those who know what they're talking about.

I'm trying to be less of a "good enough that it works" and more of a "know why it works and if its a good decision".

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!