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.
- Determine if you are hosting or connecting to a host
- Call HostGame() or Connect() accordingly.
- Call IsConnected() to see if the connect succeeded.
- Read messages from the server or from other clients.
- Call HandleEvent() from your WinProc.
- Do something with the message you receive.
- Send messages to other players
- Make sure the player you wish to send to is connectied via
Isconnected()
- 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.
|