ServerWS Class

Overview

ServerWS is a class written to encapsulate Winsock2 for games.  There are only two ways to set up a connection, three types of messages, and a handful of other functions to worry about.  The class should deal with many of the details of Winsock2 function calls that would be difficult to use without abstracting them into a class. 

ServerWS has the concept of a player.  A player is just someone who has connected to the game server.  Players are only allowed to connect if the current session is not full.

Host Information

The host maintains a list of players currently connected to its game.  This list contains the player name, the socket they are connected on, whether or not they are still connected, and additional TCP/IP information.  The 0th element of this array is ALWAYS the host. 

The host changes this information when it receives messages from clients.  An FD_CLOSE message will set a player’s connected field to false, for instance.  New players are added when the host gets an FD_ACCEPT message; their names are set with a WS_MSG_NAME message.

Client Information

Clients also maintain a list of players connected to the game.  The client, however, has no knowledge of the sockets which the host is using to communicate with the others, nor their IP address information.  This information is largely ignored by clients, but clients do need to know a players name and a unique way to refer to them.

The way a client refers to another player is via his/her index.  As mentioned above, the first element of the players array is the host.  Subsequent elements are clients, so a client can refer uniquely to any other player by this element index. 

Clients maintain the player list information through messages sent by the server.  The server should send a WS_MSG_NAME message to all clients, for instance, when a new player joins.  The server also sends a WS_MSG_DROP message to all clients when a player drops.  This way, every client is informed.

ServerWS Transparent Variables / Member Functions

ServerWS implements a few access functions for the boolean values isConnected and isHost, as well as player names, the number of current players, and the last error message.

It should be noted that for many of the functions, a boolean value is returned.  True means success and false means failure, and an error string should be copied inside the class, accessible by LastError().

Basic Usage

Before getting into function specifics, it may be helpful to understand the common sequence of function calls.

  1. Determine if you are hosting or connecting to a host
    1. Call HostGame() or Connect() accordingly.
    2. Call IsConnected() to see if the connect succeeded.
  2. Read messages from the server or from other clients.
    1. Call HandleEvent() from your WinProc.
    2. Do something with the message you receive.
  3. Send messages to other players
    1. Make sure the player you wish to send to is connectied via Isconnected()
    2. Call SendChatMesg() or SendGameMesg() with a string containing the data you want sent.

Function Prototypes

ServerWS

Constructor

Headers

ServerWS “ServerWS.hxx”

Prototype

ServerWS();

Parameters

None.

Return Value

No return value.

Remarks

This function initializes the Winsock2 engine, requesting version 2.2.  This function then initializes the ServerWS class, allocating memory for an incoming message buffer, and setting default startup values.


~ServerWS

Destructor

Headers

~ServerWS “ServerWS.hxx”

Prototype

~ServerWS();

Parameters

None.

Return Value

No return value.

Remarks

This function calls Disconnect() and then deallocates memory associated with the global incoming message pointer.


CheckIP

Validates a string as an IP address.

Headers

CheckIP “ServerWS.hxx”

Prototype

bool CheckIP(char *ip, char *reason);

Parameters

ip

            The string to validate.

reason

A return string giving the reason why ip was not validated, if false is returned.

Return Value

Returns true if ip is a valid IP address, and false otherwise.

Remarks

This function goes through a series of tests to see if the string is in fact an IP address.  If it fails a test, an error message is copied to reason and false is returned.


Connect

Attempts to establish a connection with a host which is hosting a session via HostGame().

Headers

Connect “ServerWS.hxx”

Prototype

bool Connect(HWND hwnd, UINT msg, char *ip, 
                  int port, char *play_name);

Parameters

hwnd

A handle to a window which will be sent a message every time a socket message is generated.

msg

An integer value that gives the app-specific message to be sent to hwnd when a socket message is generated.

ip

A valid ip-address given as a string, where the server is located.

port

The port that the client should attempt a connection to.

play_name

A string representing the name that this client wishes to be called.

Return Value

Returns true if none of the Winsock connection calls fail, and false otherwise.

Remarks

This function attempts to connect to a host at the ip address and port specified.  It also sets up an asynchronous mechanism for receiving messages from this connection.  When the socket receives new data or is disconnected from the host, a user-defined message msg is sent to the window handle hwnd given. 

Lastly, once these tasks have completed, the client’s own player name is set, and a WS_MSG_NAME message is sent to the host to communicate what this player wishes to be called.


Disconnect

Shuts down the socket which may or may not be connected to the server.

Headers

Disconnect “ServerWS.hxx”

Prototype

void Disconnect();

Parameters

None

Return Value

No return value.

Remarks

Simply shuts down the socket, closes it, and sets isConnected to false.


GetIndex

Returns our own player index.

Headers

GetIndex “ServerWS.hxx”

Prototype

int GetIndex();

Parameters

None

Return Value

No return value.

Remarks

Each host/client maintains a list of player information, and each host/client also knows the index of itself in the current session. 


GetPlayerName

Returns the name of the player given by an index.

Headers

GetPlayerName “ServerWS.hxx”

Prototype

bool GetPlayerName(char *name, int index);

Parameters

name

A string where the name should be copied to.

index

An integer which specifies the player index whose name we want.

Return Value

Returns true if the index is valid; false otherwise.

Remarks

Each host/client knows how many players are currently connected.  The 0th index refers to the host, and the other 1..numplayers-1 indices refer to different clients.


HandleEvent

Handles a socket-specific message.

Headers

HandleEvent “ServerWS.hxx”

Prototype

void HandleEvent(HWND hwnd, UINT msg, WPARAM socket, LPARAM 
                 event, char *mesg, int& type, int& from);

Parameters

hwnd

The handle to the window which has received this message.

msg

The message which was sent.

socket

The socket where this message originated from.

event

The type of event that has occurred.

mesg

A string where any incoming messages should be copied to.

type

An integer which should be set to the message type.

from

An integer which should be set to the index of the player this message came from.

Return Value

No return value.

Remarks

This function must be called from WinProc when it receives a socket message.  The message is set when calling HostGame() or Connect().  Depending on whether the recipient is the host or a client, this function will handle some of the details of maintaining the player list, routing information to clients, reading data from the socket, or notifying the application when a player has dropped.

After the message has been handled, WinProc should test the message type for events it is interested in and respond accordingly.  type is set to one of WS_MSG_NAME, WS_MSG_CHATSTRING, WS_MSG_GAMEPLAY, or WS_MSG_DROP, and each of these could be handled in its own way.

 


HostGame

Begins a session as the host on the current machine.

Headers

HostGame “ServerWS.hxx”

Prototype

bool HostGame(HWND hwnd, UINT msg, int port, char 
              *play_name, int maxplayers);

Parameters

hwnd

The handle to the window which will start receiving socket messages.

msg

The message which will be sent.

port

The port where the host should listen for connections.

play_name

The name of the player hosting the game.

maxplayers

The maximum number of players we want playing in our game.

Return Value

Returns true if no errors occur while calling Winsock2 functions; false otherwise.

Remarks

This function creates a socket, binds it to a port, and begins listening to it.  It does not call accept(), however, because the socket is set to asynchronous mode.  When a client attempts connection to this host, a socket message msg will be sent to the window handle hwnd so that the connecting client can be accepted only when he/she arrives. 

This function also copies some information into the player list’s 0th element about itself.


IsConnected

Returns

Headers

IsConnected “ServerWS.hxx”

Prototype

bool IsConnected();

Parameters

None

Return Value

Returns true if the host/client is currently connected, false otherwise.

Remarks

Simply reports the state of the connection.


IsConnected

Returns true if the specified player is connected.

Headers

IsConnected “ServerWS.hxx”

Prototype

bool IsConnected(int index);

Parameters

index

The index of the player we wish to query on.

Return Value

Returns true if the host/client specified is currently connected,  and false if they have dropped / disconnected.

Remarks


IsHost

Returns true if the current player is the host.

Headers

IsHost “ServerWS.hxx”

Prototype

bool IsHost();

Parameters

None

Return Value

Returns true if the current player is the host.

Remarks


LastError

Copies the last error message into a buffer.

Headers

LastError “ServerWS.hxx”

Prototype

void LastError(char *err);

Parameters

err

A string which is to receive a copy of the last error message.

Return Value

No return value

Remarks

Many of the public functions in ServerWS set a last-error string when they return a false value so that the main application can see what the error was.


NumPlayers

Returns the number of players in the game.

Headers

NumPlayers “ServerWS.hxx”

Prototype

int NumPlayers();

Parameters

None

Return Value

Returns the number of players in the game.

Remarks

When a player connects, the number of players increases.  No more players are admitted if the number of players becomes equal to maxplayers.  But, when players drop / disconnect, the number of players does NOT decrease.  The dropped player’s connected flag is set to false, but they are not removed from the list and numplayers is not decremented. 

This is done to prevent new players from connecting while others are in the middle of a game; usually that is undesirable.


SendChatMesg

Sends a “chat” message to another player.

Headers

SendChatMesg “ServerWS.hxx”

Prototype

bool SendChatMesg(int indexTo, LPSTR lpstr, bool everyone);

Parameters

indexTo

            The index of the player to send to.

lpstr

            The chat string to send.

everyone

            A flag which indicates if the message is to be sent to everyone or not.

Return Value

Returns true if the message has been sent without error to all the specified players, false otherwise.  If false, lasterr is set.

Remarks

There are two basic kinds of messages to send between any two players: Game messages and Chat messages.  Chat messages are simply meant for textual communication between players.  Game messages are sent only to the host, and give information related to gameplay input. 

Note that if everyone is set, that the indexTo parameter is ignored.  If host, SendChatMesg is responsible for sending the string to all clients.  Otherwise, the client must send a chat message to the server, which must relay the message to the right client.


SendGameMesg

Sends a “game” message to another player.

Headers

SendGameMesg “ServerWS.hxx”

Prototype

bool SendGameMesg(int indexTo, LPSTR lpstr);

Parameters

indexTo

            The index of the player to send to.

lpstr

            The game string to send.

Return Value

Returns true if the message has been sent without error, false otherwise.  If false, lasterr is set.

Remarks

There are two basic kinds of messages to send between any two players: Game messages and Chat messages.  Chat messages are simply meant for textual communication between players.  Game messages are sent only to the host, and give information related to gameplay input. 

Unlike SendChatMesg, there is no everyone parameter.  By default, messages can ONLY be sent to the host; the host must relay information itself.  Therefore, indexTo is ignored if client.


All material Copyright (c) 2001-2017 Hexar
Please direct all inquiries, love letters, and hate mail to .

Home •  Self •  Articles •  Code •  Resume •  WinTetris