Blocking, non-blocking, and asynchronous socketsHere is where I have to stop for a bit and discuss some more theory. So far we have only been using blocking sockets. When we call accept (), the function just sits there waiting for a connection request to be made. That is what blocking means. The function will just sit there waiting for an event or an error to occur. This type of socket is the default type created with the socket () command. The next type of socket is the non-blocking socket. With a non-blocking socket, functions such as accept () return immediately after being called, returning either an error, a good result, or nothing (meaning that the result will come in later). These sockets are computationally inefficient as you will find yourself writing tight while loops waiting for some even to finally happen. It is not good practice to use these sockets. Non-blocking sockets can be made using the select () command. I will not show you how to use them since there is a better way of making sockets that don't block. Asynchronous sockets are Win32 specific. They are sockets that, like non-blocking sockets, return immediately. The difference is that you give the setup function a windows message that it should send when the desired event has occurred. This way you can say:
This is great if you are using MFC or the Win32 API. You can do other things like draw graphics, receive user input, etc. while waiting for some socket event to occur. What type of socket should I use now?For server applications, use blocking sockets, as they are the most logical, simple, and practical when all you want to do is wait for a connection and then communicate with the client. For client applications, use asynchronous sockets, as they are the most efficient when you want to do other things than just sit around and eat CPU cycles. Using asynchronous socketsAlright. You know how to make blocking sockets and now its time to learn the best client type socket. This is the prototype of the function we're interested in:
SOCKET s should be clear. hWnd is the window handle of your application (which is main_window_handle if you happen to be using André LaMothe's gaming console for DirectX as a framework J). wMsg is which message you want to be sent to your application if the desired event occurs. lEvent specifies the event(s) that will cause WinSock to send wMsg to your application. Here are some flags you can use: FD_READ - On receiving data Just OR (|) them together if you want more than one. Note that these are not all the flags you can use, but these are the only really useful ones for client applications. When you add code to handle your new "socket" event in your application's message handler, you will need to know two macros. WSAGETSELECTERROR () is used to find out if there happened to be an error. WSAGETSELECTEVENT () is used to find what event has triggered the message.
Get it? Notice how only the lparam parameter and not the wparam is used. |
|