It is a fortunate thing that the server and clients share so many properties, it means we'll be able to share a lot of code between them and simplify our lives. To this end cComm will be the base class for both our client and server communications. Let's start by taking a look at what the client and server have to do in order to connect to the internet via TCP/IP. This model is known as a connection-oriented.

Client

Initialize Winsock 2.0.

Obtain an IP and port of a game on the internet. An IP could be an address (www.flipcode.com) or a number (24.112.84.101). A port is any number between 1 and 65535, inclusive.

Create a socket.

Resolve the address using gethostbyname() or gethostbyaddr()

Try to connect() to the server.

send() and recv() data on the open socket

closesocket() and shutdown()

Cleanup Winsock

Server

Initialize Winsock 2.0.

Obtain the port number the listen socket should be opened on. This is the socket clients will connect to.

Obtain the IP name and number of the machine for the sysadmin's benefit.

Create a socket.

bind() the socket.

listen() on the socket for client connections.

accept() connections on the socket unless there's some reason not to (such as banned IP, hammering or max clients)

send() and recv() data on the client socket.

closesocket() for the client

closesocket() the listen socket

shutdown()

Cleanup Winsock

A surprising number of similarities, wouldn't you say? Each needs code to...

...resolve an internet address into something Winsock 2.0 can use.
...create or destroy a given socket.
...send or receive data on a given socket.

Note that a listen socket isn't quite the same as a connection socket. More on that later.

Initializing and cleaning up Winsock is easy as pie. Just ask it what version you'd like (2.0, in our case) and then check to see that there weren't any major errors. The only thing to really pay attention to is that every call to WSAStartup is matched with a call to WSACleanup because the winsock system relies on wsock32.dll. If you've never worked width DLLs, here's a ten second explanation: DLLs contain reusable system code that only take up memory once in the machine. Every time you use a DLL you increment an internal counter. When you finish you decrement the counter and when that counter reaches zero the DLL is unloaded from memory. Simple, effective and very dangerous to available memory if you don't get it right.

The next job is to resolve the IP address of the local machine, in nnn.nnn.nnn.nnn style. This is a little more complicated because winsock 2.0 calls the network subsystem and then returns control to the application. A short while later the window you have running will receive a message indicating that the address has been resolved.

Once a valid IP has been obtained our next job is to create or destroy a given socket. Again, this is a fairly simple task. The only problem is that when you want to destroy the socket you have to make sure there's no data left to be read on the socket. Though I've never tested, I bet you'd get a memory leak if you didn't read it in. Note that the following code is only version one, we'll be adding more later.

int cComm::Disconnect() {
// SOCKET d_socket;
// shutdown() warns the other machine no more data
// Will be sent on this socket.
shutdown( d_socket, SD_SEND );

// Read in the remaining data pending on this socket
// Shut down the socket.
closesocket( d_socket );

return 0;
}

So let's review: We can now initialize Winsock, find the local IP and create a socket. Then when the application ends we destroy the socket and cleanup Winsock. Next week we'll take that open socket and connect to a remote machine.