Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
79 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Contents
 Introduction
 Setting Up
 Notification
 Messages

 Shaking Hands
 Sending and
 Receiving


 Printable version
 Discuss this article
 in the forums


Shaking Hands - Connecting and Accepting

Now the fun begins. We are going to place a call to connect() with the client app, send an accept() with the server app, and then process an FD_CONNECT message. Are we ready? Then let’s first call the connect() function. Where you ask? Well, where you normally would. Let’s not get this mixed up - the FD_CONNECT event happens after the connection has been established, so you don’t call connect from the FD_CONNECT event handler, we’ll get there soon. Just call connect() as you normally would, after you set all the IP addresses and port numbers and so on.

connect(Port, (LPSOCKADDR)&Server, sizeof(Server));

NOTE: It’s important to know that all asynchronous functions will return the error WSAWOULDBLOCK at some point. This error can trip you up if you aren’t ready for it, even though it is vital to the FD_WRITE event, as we’ll see. So if you do any error checking, be sure to pass over this error, since it really isn’t one.

Now, the call to connect has been sent, and your program goes into a wait state (unless you have something else for it to do in the meantime). So since it’s so boring over here, let’s hop on over to the server where it is just now receiving your connection request. And what happens? An FD_ACCEPT event is generated! Quick! To the Batcave Robin! Err, sorry - got carried away there. So now the server grabs the message and it pops into its queue. The message handler picks it up and - what do we do? Have no fear, we simply have to be friendly and call accept().

...
case FD_ACCEPT:
  {
    // holds size of client struct
    int lenclient = sizeof(client_sock);

    // connect to the server
    Port = accept(wParam, &client_sock, &lenclient);
  } break;
...

Now that the server has done his job, let’s jump on back over to the client and see what he’s up to. And look at that. He’s received the acceptance, and now he’s generated an FD_CONNECT event. Here we go - off to the message handler. Now what? Well, this event is a place where you can perform any number of tasks that need to be done right after connection has been established. While in an FD_ACCEPT event you have to call accept(), in an FD_CONNECT event you don’t have to do anything - although it is a good idea to set a variable or let the user know you’re connected.

Re-enabling Functions

Now some people may whack me for getting out of line here, but I feel it’s a good time to explain this concept before have to cover the FD_WRITE message. The way WinSock handles messages is that it only posts one at a time. Once a message is posted, no other messages are posted until they are handled, and a re-enabling function is used.

For example, the re-enabling function for FD_ACCEPT is accept(). When an FD_ACCEPT event is posted, no other message will be posted until the application handles the current one and then calls accept(). Once accept() is called, if there is already another connection request, FD_ACCEPT is posted again immediately. If not, WinSock waits for one or posts another pending event.

The point is that without calling accept() you do not re-enable WinSock to send more FD_ACCEPT messages (or any other messages, for that matter). Needless to say, this can be a problem J. There are only two other events that require a re-enabling function. Those are FD_READ and FD_WRITE. Their re-enabling functions are recv() and send(). Gee. What a surprise.





Next : Sending and Receiving Data