<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
	<title>Multiplayer and Network Programming - Articles</title>
	<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/</link>
	<pubDate>Sat, 25 Feb 2012 22:08:48 +0000</pubDate>
	<ttl>43200</ttl>
	<description>Resources for networking in games</description>
	<item>
		<title>Clock Synchronization of Client Programs</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/clock-synchronization-of-client-programs-r2493</link>
		<description><![CDATA[<br />
<strong class='bbc'>Introduction</strong><br />
 Multiplayer games often need to deal with the complex nature of the networking technology. Most notably, multiplayer games on Internet represent a greater challenge to the developers than those games written only to run on LAN environment. One of these challenges is the delay that exists from the time at which a process sends a message over the network to the moment at which the message is received by the other process. This delay is known as network latency, itÆs both a consequence of our worldÆs physic constraints and the design of the networking technology (protocols). <br />
<br />
Network latency, informally known as LAG, represents a serious challenge to multiplayer game developers. The LAG can have disastrous effects on the playerÆs gaming experience, making the game unplayable. <br />
<br />
The latency can change over the course of a game session, this dynamic behavior of the network requires a solution that can detect this changes and react to minimize their impact in the game. <br />
<br />
Client clock synchronization is a simple technique that can be used to cope with network latency. ItÆs not a magic solution but in some specific cases can greatly improve the experience of the users, masking the effects of network latency and making the game look pleasant and fair. <br />
<br />
The present document describes how to synchronize client clocks over the network. The first part of the document describes how the messages are encoded before sending them over the network. The closing part of the document describes the messages that the clients and the server exchange in order to synchronize the clocks. <br />
<br />
<br />
<strong class='bbc'>Game scenario</strong><br />
 Remember that our goal is that the game can react to the networkÆs dynamic behavior. For this purpose we are going to suppose that we are working on a simple arcade multiplayer game in which two players compete. <br />
<br />
The programsÆ clocks are the main and only synchronization mechanism in which we are going to be relying on to achieve our goal.  A clock is just a simple counter ranging from 0 up to N, the current value of a clock represent the number of milliseconds that have elapsed since the game began.  <br />
<br />
ItÆs essential that when a game session starts, that is when the game itself begins, all the three clocks (two clients and server) be synchronized and have the initial value set to zero. The algorithm described later on this article will let us do this. <br />
<br />
Once the clocks are synchronized we can use them for at least three very important functions: <br />
<br />
<ul class='bbc'><li>The server can report to the clients key state changes in the game environment. </li><li>The server can use the clock along to the clientsÆ messages timestamps to arbitrate conflicts. </li><li>Clients can use the clocks and incoming messagesÆ timestamps to detect network latency changes. When the client notices a change in the latency, it will scale the speed of the local Avatar to minimize the effect of the latency.</li></ul> Here is a C++ class for the gameÆs virtual clock:  class VClock {   DWORD mRealStart;   bool  mStarted; public:   VClock() : mRealStart(0) {} ;   bool Started() const { return mStarted ; }   void Start( DWORD time_delta )    {      mRealStart=GetTickCount()-time_delta; 	mStarted=true;    }   DWORD getTime( ) const 	{      assert(mStarted) ; 	return GetTickCount() - mRealStart;    } };  The function GetTickCount retrieves the number of milliseconds that have elapsed since the computer was turned on. The value returned has 8 bytes long and the biggest value can be 49.7 days, which is more than enough for a game session! Otherwise the player is in grave danger and needs to get help. The real clock is the value returned from the GetTickCount. The virtual clock is the value of GetTickCount minus the instant in which the server signaled the begin of a game session. <br />
<br />
<br />
<strong class='bbc'>Application Messages</strong><br />
 The game client communicates with the server by sending messages over the network, the transport protocol used by the game is TCP. A message is a piece of information that the client/server wants to communicate, e.g. one player has pressed the mouseÆs left button. <br />
<br />
<br />
<strong class='bbc'>Game Message Layout</strong><br />
 <span rel='lightbox'><img src='http://images.gamedev.net/features/programming/clocksync/fig1.jpg' alt='Posted Image' class='bbc_img' /></span> <br />
<br />
The field <strong class='bbc'><em class='bbc'>ID</em></strong> has two bytes long, itÆs an integer used to identify the different messages. <br />
<br />
The values of this field are declared in the program as an enumerative type: <br />
<br />
 typedef enum commands  {   cmdLOGIN                  = 0x1U,   cmdERROR                  = 0x2U,   cmdLOGIN_OK           	= 0x3U,   cmdMOUSE_LEFT_BUTTON_DOWN = 0x5U,   cmdREADY                  = 0x9U,   cmdBEGIN_GAME         	= 0x10U,   cmdGAME_END           	= 0x11U,   cmdSYNCH_REQUEST          = 0x12U,   cmdSYNCH_REPLY            = 0x13U,   cmdPRIMARY_CLIENT     	= 0x14U,   cmdSECONDARY_CLIENT   	= 0x15U,   cmdSYNCH_DONE         	= 0x16U,   cmdSYNCH_WAIT         	= 0x17U } protoCommands;  The field <em class='bbc'><strong class='bbc'>SIZE</strong></em> has two bytes and specifies the size of the message measured in bytes. The smallest message has a size of 4 bytes. The field <em class='bbc'><strong class='bbc'>DATA</strong></em> has variable length. This field is used to communicate additional information, e.g. the field data of the message cmdMOUSE_LEFT_BUTTON_DOWN has the mouse position of the remote user. <br />
<br />
The fields are encoded/decoded using the standard socket functions htons, ntohs, htonl and ntohl. These functions convert a 16-bit / 32-bit number from the host byte order (little-endian on Intel processors) to the network byte order (big endian) as well as the opposite. <br />
<br />
The field <em class='bbc'><strong class='bbc'>TIMESTAMP</strong></em> has 4 bytes, please note that this field is only used once the clocks have been synchronized. When sending messages, the clients always store their virtual clock value here. <br />
<br />
<br />
<strong class='bbc'>Clock Synchronization Algorithm</strong><br />
 In order to synchronize the client clocks the programs need to estimate the network latency: the amount of time it takes a message to travel from one client program to the other one. Therefore the clock synchronization process has two steps: 1) compute network latency and 2) signal clock synchronization. <br />
<br />
The diagram below shows the messages that are exchanged to accomplish the clock Synchronization: <br />
<br />
 <span rel='lightbox'><img src='http://members.gamedev.net/gaiiden/fig2.jpg' alt='Posted Image' class='bbc_img' /></span> <br />
<br />
 <ol> Client #1 establishes a TCP connection to the Game Server and sends the message cmdLOGIN. This message includes the ID of the game that the client wants to join to. <li>Upon receipt of the message cmdLOGIN, the server checks if the requested game already has a primary client associated to it. If there is no primary player the server assigns this role to the client and sends the message cmdPRIMARY_CLIENT.<br />
<br />
 <li>Client #1 receives the cmdPRIMARY_CLIENT message. The client sends the cmdSYNCH_REQUEST message to the server and records the time at which the message was sent.<br />
<br />
 <li>The Server receives the cmdSYNCH_REQUEST message, but as the other player has not joined to the game yet, the server sends back to Client #1 the message cmdSYNCH_WAIT. This message tells to the client that it should try again later.<br />
<br />
 <li>Client #1 sends the cmdSYNCH_REQUEST message to the server and records the time at which the message was sent.<br />
<br />
 <li>Item 4.<br />
<br />
 <li>Client #2 establishes a TCP connection to the Game Server and sends the message cmdLOGIN. This message includes the ID of the game that the client wants to join to.<br />
<br />
 <li>Upon receipt of the message cmdLOGIN, the server checks if the requested game already has a primary client associated. The primary player already joined to the game, so the server assigns the secondary role to this new client and sends to it the message cmdSECONDARY_CLIENT<br />
<br />
 <li>Client #1 sends the cmdSYNCH_REQUEST message to the server and records the time at which the message was sent.<br />
<br />
 <li>The Server forwards to the Client #2 the message cmdSYNCH_REQUEST<br />
<br />
 <li>Client #2 receives the message cmdSYNCH_REQUEST and sends the message cmdSYNCH_REPLY to the server.<br />
<br />
 <li>Client #1 receives the message cmdSYNCH_REPLY and records the time at which it has been received. <br />
<br />
 [The programs repeat the steps 9,10,11 and 12 several times. The cmdSYNCH_REQUEST messages are spaced by 20 milliseconds] <br />
<br />
<li>At this point the primary client has gathered the data needed to estimate the latency, so now the client computes the latency, sets its clock to 0 and sends the message cmdSYNCH_DONE.  This message includes the estimate of the latency. The primary client uses the following statistics to estimate the latency: A(n) = time at which the Nth cmdSYNCH_REPLY was received<br />
B(n) = time at which the Nth cmdSYNCH_REQUEST was sent<br />
X(n) = A(n) û B(n) / 2 <br />
<br />
<ol> <li>Sort the X(n) from smallest latency to largest and choose the median value. <li>Compute the standard-deviation s = ( Σx<sup class='bbc'>2</sup> - (Σx)<sup class='bbc'>2</sup>/ n ) / n û 1]]></description>
		<pubDate>Mon, 14 Apr 2008 13:36:01 +0000</pubDate>
		<guid isPermaLink="false">5ba6a3726dd462084373f54a217a9162</guid>
	</item>
	<item>
		<title>Shaving Ping</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/shaving-ping-r2319</link>
		<description><![CDATA[

<a name="expectationmore_go_for_less_dough" id="expectationmore_go_for_less_dough"></a>
<h1>Expectation: More Go for Less Dough</h1>
<p>The gaming user community is always changing. As new DSL, fiber, and cable modem solutions are bringing lower cost, higher bandwidth connectivity the home user, expectations rise among casual and
die hard on-line gamers alike: more, better, faster! And their personal measure of connection success is ping. The perception remains: "good ping" means "good play". The game hosting companies, game
publishers, and individuals who host network game servers are on the hook to deliver the goods. A rented server with a T1 connection for 32 players hosting a Half-Life Counterstrike server might have
gone for $150 per month a couple of years back. Now they can be had for $25. So how is a game server hosting company supposed to make money?</p>
<p>One way hosting companies have managed to make this happen is with higher performance hardware. Newer P4-generation and recent dual-core machines, running server class flavors of Windows or Linux,
are able to host multiple game engines on the same system.</p>
<p>Another cost management development for gaming hosts is the "self-managed" game server. In the same way that tools like Webmin <a href="#fn1" name="fnt1" id="fnt1">1)</a> have enabled web server
hosting companies to offer $5 per month web hosting to thousands by lowering their own administrative costs, a refined set of public domain and cheap game administration remote admin tools have made
it relatively easy for the game server hosting companies to pass on routine maintenance issues for their rented servers to even mildly technical customers, whether it be uploading of new game maps
and player files to stopping and starting different configurations of game server processes.</p>
<a name="server_squeezehow_to_get_more" id="server_squeezehow_to_get_more"></a>
<h1>Server Squeeze: How to Get More</h1>
<p>So the network and the server hardware are in place. There are as many customers as the infrastructure can bear. What else can be done to improve the performance, and possibly the capacity,
without adding more hardware? One approach that remains is to get the server software itself to run better.</p>
<p>This means working to "adjust" the server binaries to improve their performance. This assumes, of course, that you have access to the source code for the game server programs. If you are a game
developer or part of the mod community for your favorite game, you may already have access to the game source. If you are a big enough customer of the game (for example a large gamer caf&eacute;
owner), or a big sales enabler (by virtue of the large number of servers you host for Company X's latest release), you may be able to negotiate access to the source or convince the vendor to make
some performance improvements of their own on your behalf.</p>
<p>Assuming you have access to the source, you can take several steps down the optimizing path, including application of processor-agnostic general optimization and optimization targeted to your
server hardware's specific processor type, including 64-bit architectures.</p>
<a name="general_optimization" id="general_optimization"></a>
<h1>General Optimization</h1>
<p>A good first step toward beefing up your server program is to compile it with an effective optimizing compiler. One choice is the Intel C/C++ Compiler <a href="#fn2" name="fnt2" id="fnt2">2)</a>,
available in both Linux and Windows flavors. If the server is a Windows system, the software developer can use their pre-existing Microsoft DevStudio IDE to manage projects and compiles, with the
Intel C and C++ compilers underneath. If the server is a Linux system, the user can choose to use the Eclipse software development CDT environment or good, old fashioned command line editors and
"make".</p>
<p>How to start? For this exercise, a solid game engine example was selected: Richard Stanway's R1Q2 <a href="#fn3" name="fnt3" id="fnt3">3)</a>. This is a tightened and enhanced version of the Quake
2 engine, which was release to the Open Source community by ID Software back in 2001. Older code? Yes, but many game programmers cut their teeth on Q2 mod development. It's a known space and a good
reference point. Rich's R1Q2 was coupled with code from the LOX Q2 mod, an "extreme weapons" mod built by David S. Martin and friends, and enhanced by Geoff Joy and others. The LOX mod is a good
example of performance challenging code, as the massive number of events that can be created by a single player with the right weapon selections and feature combinations can bring an otherwise
healthy server to its knees.</p>
<p>Again for this example, the target server platform is Linux, the default choice among server hosting companies where game server engines have a Linux server offering. The test server used was a
vanilla Red Hat Enterprise Linux 3 (Taroon Update 4) server, running on a 3.7 GHz Pentium 4 with 1 Gig of RAM, spinning a standard Serial ATA hard drive. Note that all of the steps being discussed
here, including the optimization techniques and compiler features, are applicable to or available on Windows as well.</p>
<h2>Step One:</h2>
<p>Get the code. Unwrapping the code and doing a straight gcc compile using the ---O2 optimization switch with the provided makefiles generated usable binaries that performed as expected. A pair of
client machines running on an isolated net connected without issue and achieved pings from varying from 15 to 35 ms. Since this code has had some level of grooming, compiler warnings were
minimal.</p>
<h2>Step Two:</h2>
<p>Perform reference benchmarking. In this case, two client machines were connected to the server, running its standard version of binaries, from a local network connection. Their static pings were
recorded, as were their pings when the server was stressed. In this case, the stress test involved having the players from both client test machines launch 4 napalm grenades per second from a fixed
location on the servers default level, generating at least 128 in-game explosions per second. Client "freeze" behavior, typical in this server stress condition, was monitored, as was the frequency of
"RATEDROP" warnings, issued from the server when a significant drop in server-client data exchange rate is detected.</p>
<h2>Step Three:</h2>
<p>Get the Intel compiler. The Intel C/C++ compiler package is available for demo download, with academic, non-commercial, and commercial licenses. The software installs on nearly all major Linux
distributions, including those not supporting RPM.</p>
<h2>Step Four:</h2>
<p>Update the makefiles to enable optimization options. In this case, that meant changing "CC=gcc" to "CC=icc". The R1Q2 makefile required no dependency changes or LDFLAGS changes. The LOX makefile
required a minor change to the LDFLAGS setting to accommodate the new library home for a couple of key string functions.</p>
<p>For round one of our compiler optimization exercise, CFLAGS was changed to add the <strong>-02</strong> optimization switch. This is the most commonly recommended option, performing many
optimizations for speed without significant regard to the impact on code size, including but not limited to:</p>
<ul>
<li>Inlining</li>
<li>Forward substitution</li>
<li>Constant propagation</li>
<li>Dead static function, code, and store elimination</li>
<li>Tail recursions</li>
<li>Partial redundancy elimination</li>
</ul>
<p>One thing that became clear during the initial build with the Intel compiler was that the number of warnings increased, going from 4 to 62. Most of the warnings were variable type checking issues.
Some of them warranted further investigation. In this case, only minor code changes were required. The newly rebuilt binaries were tested and results gathered.</p>
<p>For the next round of optimization, the <strong>-02</strong> CFLAGS option was changed to <strong>-03</strong>. This option, according to the documentation, contains "more aggressive
optimizations, such as prefetching, scalar replacement, and loop and memory access transformations". This includes all of the features of the -02 optimization, plus loop unrolling, code replication
to eliminate branches, and padding of certain power-of-two arrays to improve cache use. Again, the newly built binaries were tested and results were gathered.</p>
<p>For round three, the binaries were built with an added switch: <strong>-axN</strong>. This switch enables processor-targeted optimization, in this case specifically for Intel Pentium 4 and
compatible chips. Once again the new binaries were tested.</p>
<p>The final round of compiler switch optimization called for changing the <strong>-axN</strong> switch to <strong>-axP</strong>. This option optimizes the output for Intel Pentium 4 processors with
Streaming SIMD Extensions 3 (SSE3) instruction support. Once more the resulting binaries were tested.</p>
<a name="test_results" id="test_results"></a>
<h1>Test Results</h1>
<p>The two client machines used for the test included:</p>
<ul>
<li><strong>Machine 1</strong> - a 2.9 GHz Pentium 4 with 512 Mbytes of RAM, running an R1Q2 Quake 2 client in OpenGL mode at 1024 x 768 resolution</li>
<li><strong>Machine 2</strong> - a 1.3 GHz Celeron with 512 Mbytes of RAM, running a stock 3.20 ID client in software rendering mode at 1024 x 768 resolution</li>
</ul>
<p>Here is a summary of the results:</p>
<table cellspacing="0" cellpadding="3" border="1">
<tr>
<td align="center" class="tblhdr">Condition</td>
<td colspan="2" align="center" class="tblhdr">Reference (gcc -O2)</td>
<td colspan="2" align="center" class="tblhdr">icc -02</td>
<td colspan="2" align="center" class="tblhdr">icc -03</td>
<td colspan="2" align="center" class="tblhdr">icc -03 -axN</td>
<td colspan="2" align="center" class="tblhdr">icc -03 -axP</td>
</tr>
<tr>
<td align="center" class="tblhdr">Machine</td>
<td align="center" class="tblhdr">1</td>
<td align="center" class="tblhdr">2</td>
<td align="center" class="tblhdr">1</td>
<td align="center" class="tblhdr">2</td>
<td align="center" class="tblhdr">1</td>
<td align="center" class="tblhdr">2</td>
<td align="center" class="tblhdr">1</td>
<td align="center" class="tblhdr">2</td>
<td align="center" class="tblhdr">1</td>
<td align="center" class="tblhdr">2</td>
</tr>
<tr>
<td>Static Ping (20 sec avg)</td>
<td>18</td>
<td>35</td>
<td>18</td>
<td>35</td>
<td>16</td>
<td>33</td>
<td>15</td>
<td>32</td>
<td>13</td>
<td>23</td>
</tr>
<tr>
<td>Stress Ping(20 sec avg)</td>
<td>50</td>
<td>60</td>
<td>50</td>
<td>58</td>
<td>45</td>
<td>55</td>
<td>43</td>
<td>53</td>
<td>42</td>
<td>49</td>
</tr>
<tr>
<td>Perceived Lag Freeze</td>
<td>YES (~3 sec)</td>
<td>YES(~6 sec)</td>
<td>NO</td>
<td>YES (~2 sec)</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
</tr>
<tr>
<td>Stress Test Frame Drop Warnings / sec</td>
<td>0.125</td>
<td>0.25</td>
<td>0.125</td>
<td>0.25</td>
<td>0.1</td>
<td>0.17</td>
<td>0.1</td>
<td>0.17</td>
<td>0.08</td>
<td>0.12</td>
</tr>
<tr>
<td>Post-stress Test Recovery to static ping rate</td>
<td>10 sec</td>
<td>14 sec</td>
<td>8 sec</td>
<td>11 sec</td>
<td>7 sec</td>
<td>10 sec</td>
<td>6 sec</td>
<td>9 sec</td>
<td>3 sec</td>
<td>6 sec</td>
</tr>
</table>
<br>
<a name="compile_optimization_conclusions" id="compile_optimization_conclusions"></a>
<h1>Compile Optimization Conclusions</h1>
<p>The above results show that there is no significant ping difference between the gcc -O2 and icc -O2 behavior during relatively inactive periods, put perceived lag on the client side is reduced
somewhat. Similarly, frame drop warning rates and recovery times after stress events are mildly better with the icc compiler. Results are somewhat more significant when going to a -O3 optimization
level and even more dramatic when including the processor targeting options -axN and -axP.</p>
<p>The above tests are not a perfect model for behavior in a dynamic environment, where players will be connecting from across the company or across the globe. But they do serve to demonstrate the
opportunity for improvement.</p>
<p>Clearly, ping is not the only measure of performance. While the improvements made to the test programs did improve ping somewhat, most of the impact was seen in the server's ability to maintain
smooth gameplay, or to restore smooth gameplay after periods of intense activity. And this is what it is all about.</p>
<a name="additional_steps_to_improve_the_binaries" id="additional_steps_to_improve_the_binaries"></a>
<h1>Additional Steps to Improve the Binaries</h1>
<p>The gains demonstrated above may be significant enough for some. If still more performance improvement is required, there are a number of additional steps that can be taken. While these steps are
beyond the scope of this article, they are worth mentioning as areas of future exploration, especially for developers of new game offerings.</p>
<p>One of these steps is to apply profilers to determine where the hotspots (bottlenecks) are in the game server program. Tools such as Intel's VTune Performance Analyzer product can be employed to
locate the sources of program slowness, identify key algorithms that can be improved, and point toward other opportunities to optimize program behavior.</p>
<p>Another approach that can work hand in hand with performance analysis is addition of threading techniques to the software. Individual hotspots in the program can be threaded, using available
threading libraries and new or modified code, to streamline program operations and to take advantage of the performance gains offered by new dual core processor technologies.</p>
<a name="other_ways_to_improve_server_performance" id="other_ways_to_improve_server_performance"></a>
<h1>Other Ways to Improve Server Performance</h1>
<p>There are, of course, fundamental things that a game server administrator can do to ensure that the game being hosted is optimally configured and makes best use of all the work that went into
coding and compiling it well. Several key server configuration parameters may be adjustable for a particular game, significantly impacting overall performance. While these vary from game to game,
they can include:</p>
<ul>
<li>Practical player limit (i.e. don't let the user adjust this number past their purchased limit or sell player count limit packages that exceed the game engine's ability to deliver)</li>
<li>Hard ceiling to connected ping of players (i.e. players with ping greater than a specific limit are not allowed to connect or are disconnected during game play to protect playability for the
rest)</li>
<li>Limited bandwidth or disabled downloading of maps, models, audio, and other optional "level-specific" content.</li>
<li>Limited bandwidth or disabled uploading of player-specific content, such as "skins" and "sprays", where such features are supported by the game.</li>
<li>Cap on frames per second performance (may be expressed as max number of player updates per second)</li>
</ul>
<p>A last option: you can always change the game. A novel approach to minimizing server performance impact from level-specific content download, adopted by Richard Stanway in his R1Q2 package,
involves outsourcing of map / texture / audio downloads to an HTTP server. This means that the map download function can be optionally offloaded to a separate system, perhaps one on a separate subnet
to minimize network impact, with transfers running at a higher UDP data rate than the game's existing TCP connections can support. The downside to doing this with an existing, released game is that
it will probably require client-side changes as well. This sort of approach would work well applied to the design of a new game server engine, and could readily be applied to a rewrite of an existing
engine where the server code has been released to the Open Source community.</p>
<p>This type of distributed data transfer between the game server and the client is also another excellent application for threading techniques. In environments supporting several Massive Multiplayer
servers, these could even be scaled up to support deployment in clustered environments, with specific components of the cluster performing particular aspects of client updating and content download
activity.</p>
<h1>About the Author</h1>
<p>Doug Helbling is a software engineer for Intel's software development product deployment team. He works to develop Linux product delivery solutions, various game mods and case studies. His latest
project includes an optimization study of GarageGames' Torgue engine.</p>
<hr>
<p><a href="#fnt1" name="fn1" id="fn1">1)</a> Webmin web-based interface for system administration <a href="http://www.webmin.com">http://www.webmin.com</a></p>
<p><a href="#fnt2" name="fn2" id="fn2">2)</a> Intel C/C++ compilers and related software products <a href="http://www.intel.com">http://www.intel.com</a></p>
<p><a href="#fnt3" name="fn3" id="fn3">3)</a> R1Q2 Quake 2 release <a href="http://www.r1ch.net/stuff/r1q2">http://www.r1ch.net/stuff/r1q2</a></p>

]]></description>
		<pubDate>Thu, 11 May 2006 09:40:39 +0000</pubDate>
		<guid isPermaLink="false">ec42787cefadf6378e1fd7917aa05b5f</guid>
	</item>
	<item>
		<title>Security Issues of Online Gaming</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/security-issues-of-online-gaming-r2062</link>
		<description><![CDATA[

<p>This article looks at several of the issues regarding security aspects of online based games and virtual worlds.</p>
<h1>Introduction</h1>
<p>As online gaming becomes a billion dollar industry and game companies are making revenue from subscription charges, new problems emerge which need to be taken very seriously. Online games
containing graphical glitches, sound defects and poor performance will not be very popular. However, an online game with security flaws and mass-cheating will simply fail.</p>
<p>Several security issues related to online gaming are shared with other network applications, however online gaming has a unique set of problems that need to be dealt with. The aim of creating a
secure game is not only to ensure customers credit card numbers are protected, but to ensure that all players receive a fair and entertaining experience. Otherwise, they won&#8217;t play.</p>
<p>This rest of this article looks at some of the security related issues in online gaming. Note that not all of the issues will apply to all types of games.</p>
<h1>Copy Protection</h1>
<p>This has traditionally been the most important aspect of security in computer games. There are many different technologies that provide copy protection, but nearly all of them can be overcome.
However, piracy is not so relevant to online games, as the game companies make money from subscriptions. Money can be made from selling boxed-versions of online games by giving added-value content
such as manuals, maps, and the box itself.</p>
<h1>Hacking the Client</h1>
<p>Many online games store game logic and player data on the server, and store graphics and sound on the client. This makes it difficult for hackers to cheat by altering statistics such as health or
ammunition; however it gives them full ability to change the graphics in a game. For many gamers, the ability to make modifications (known as mods) to games is almost as important as playing the game
itself. However, imagine if one player modifies the game so that he can see through walls, and plays against somebody who can&#8217;t. You can guess who will win. A simple solution to this problem is
by ensuring all players are using the same modifications.</p>
<h1>Packet Sniffing</h1>
<p>There are many programs available that let users examine, modify, send or block packets that are being transmitted to and from their computer. This causes several problems for online games such as
blocking packets that may have a negative effect on a player, or replaying packets that shoot an enemy player, even though you have no ammunition left. Such situations can be avoided by keeping
important variables on the server, and by encrypting packets. Even encrypted packets can be repeated though; therefore a sequence number system should be used so that the server can verify the
packets.</p>
<p>Area of Interest Management should also be used to minimize the data that the client has to receive. If a tree falls in a forest and no one is around to hear it fall, does it make a sound? In a
virtual world using AoIM algorithms, the answer is no. AoIM algorithms limit network traffic in a virtual world to only what is necessary for each player. In a large virtual world, there could be
thousands of players, with millions of variables that are constantly changing. If the client were to be kept updated with all variables, it could easily use up more bandwidth than available, causing
network congestion and increasing latency. To put very simply, AoIM solves this problem by dividing the world into different geographical zones, and then only sending data regarding the zone that is
directly related to each player.</p>
<h1>Social Abuse</h1>
<p>Players in virtual worlds can have a lot of freedom to do as they please. This could include running around causing sexual and racial abuse. Such abuse reduces and spoils the fun and can damage
the popularity of the game. There are two ways around this problem; first of all by allowing other players to report such abuse. This requires adequate logging facilities so any allegations can be
proved and then the offending player can be dealt with accordingly. Another solution to limit the damage in the first place is to give players the option of censorship. This relies on intelligent
game software detecting offensive behavior and hiding it from players who wish to be protected. Another form of social abuse could be using a game for commercial or advertising purposes, or tricking
people into giving out credit card numbers etc. This can be prevented again by reporting such abuse, and by educating users.</p>
<h1>Hacking Accounts</h1>
<p>Since a password is the key to accessing account information and the player&#8217;s character, it is important that the same password protection techniques are used as in other sensitive
applications. These can include encryption when transmitting sensitive data, and educating players not to use obvious passwords or inadvertently giving them out. In some situations, server
authentication may also be necessary to ensure hackers have not setup bogus servers that can be used to collect a user&#8217;s password.</p>
<h1>Denial of Service</h1>
<p>Such attacks can be used to reduce the responsiveness of other players. This is hard to avoid when using a peer-to-peer topology, however in client-server based games, simply not distributing
other players IP addresses will avoid this problem. Attacks on game servers are also possible. This is unlikely to give any specific player an advantage, but it is likely to make the game unplayable
for everybody. Using server software that drops non-game packets and technology such as XenoService will help to reduce the effects of such attacks.</p>
<h1>Internal Misuse</h1>
<p>This could be either accidental or deliberate. System administrators responsible for the virtual world are probably enthusiastic players in the game itself. But can they be trusted not to abuse
their god-like position? Or perhaps a system administrator decides to make a few changes to the game world without fully considering possible implications. Therefore powers should be restricted where
possible, monitoring is necessary, and procedures must be set in place and followed.</p>
<h1>Backup</h1>
<p>Due to the complexity and nature of virtual worlds, it is essential to keep several versions of backups from different time periods. For example, if a serious bug is found after many players have
taken advantage of it, this could cause a major unbalance in the economics of the world. It is often better to restore the game from a time before the bug was taken advantage of, than letting play
carry on as is &#8211; even if it means losing several days worth of play. Most players would prefer this than having to start again from scratch.</p>
<h1>Cheat Detection</h1>
<p>By logging access to game servers, recording important events (e.g. player advancement), and keeping track of key quantities such as the number of rare items in the game, game administrators can
identify or verify where cheating is taking place.</p>
<h1>Disconnecting</h1>
<p>A player may disconnect from a game seconds before being killed, perhaps then reconnecting with another character and finishing off the battle. Although two can play at that, nobody will die, the
game becomes boring and good players will stop playing. This can be solved by game design, for example by making a character go into an auto-pilot mode for a period of time after disconnection.</p>
<h1>Disciplinary Measures</h1>
<p>Games should include a comprehensive list of terms and conditions that will allow termination of players who break the rules. However, it is essential mistakes are not made, as one wrongly banned
customer could cause an uproar. Also, it could be difficult to stop banned users from signing up again, especially from free systems that do not require credit cards numbers.</p>
<h1>Conclusion</h1>
<p>It is probably impossible to make a perfectly secure online game; however it is certainly possible and desirable to reduce and limit misuse, allowing customers a good experience in a virtual
world. Good design and programming, increased user awareness, ongoing maintenance and supervision will help to achieve this.</p>
<h1>References</h1>
<p>Becker, David, ZDNet Article, Cheaters take profits out of online gaming, June 2002<br>
<a href="http://zdnet.com.com/2100-1104-933853.html">http://zdnet.com.com/2100-1104-933853.html</a></p>
<p>Internet Security Systems, Packet Sniffing<br>
<a href=
"http://www.iss.net/security_center/advice/Underground/Hacking/Methods/Technical/Packet_sniffing/default.htm">http://www.iss.net/security_center/advice/Underground/Hacking/Methods/Technical/Packet_sniffing/default.htm</a></p>
<p>Gamasutra, How to Hurt the Hackers: The Scoop on Internet Cheating and How You Can Combat It<br>
<a href="http://www.gamasutra.com/features/20000724/pritchard_01.htm">http://www.gamasutra.com/features/20000724/pritchard_01.htm</a></p>
<p>Nathaniel Baughman, Brian Neil Levine, Cheat-Proof Playout for Centralized and Distributed Online Games, 2001<br>
<a href="http://citeseer.nj.nec.com/baughman01cheatproof.html">http://citeseer.nj.nec.com/baughman01cheatproof.html</a></p>
<p>Wired, Blizzard of Cheaters Banned<br>
<a href="http://www.wired.com/news/games/0,2101,55092,00.html">http://www.wired.com/news/games/0,2101,55092,00.html</a></p>
<p>XenoService<br>
<a href="http://www.ftp.cl.cam.ac.uk/ftp/users/rja14/xeno.pdf">http://www.ftp.cl.cam.ac.uk/ftp/users/rja14/xeno.pdf</a></p>

]]></description>
		<pubDate>Wed, 10 Mar 2004 18:15:32 +0000</pubDate>
		<guid isPermaLink="false">60be21f3ebf28ff7b8a692a752d92cf8</guid>
	</item>
	<item>
		<title>Distributed Gaming</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/distributed-gaming-r1948</link>
		<description><![CDATA[Distributed Gaming<br />
by <a href='mailto:omar.abdelwahed@bestbuy.com' title='E-mail Link' class='bbc_email'>Omar A. Abdelwahed</a><br />
Revision 1.1<br />
<br />
 <br />
<strong class='bbc'>Abstract</strong><br />
 This document discusses the concept of "distributed gaming" and the Meesha Network implementation. Distributed gaming allows the specification of application-level resources within a game design. These resources are distributed across a network of peers where multiple peers may serve identical resources. Through a trust relationship, these peers are able to dynamically locate one another and individually determine the best resources available from their own specific view of the network. This allows a high degree of scalability that is both flexible and specific to a resource. As well, distributed gaming creates a means to aggregate the total bandwidth across the network of peers.<br />
<br />
 It is the goal of this document to show how distributing gaming will dramatically benefit network intensive games.<br />
<br />
 <br />
<strong class='bbc'>Background</strong><br />
 Distributed computing and peer networks have been around for a long time [1]. There have been several well-known topologies with recent popular implementations seen in such applications as <a href='http://www.napster.com/' class='bbc_url' title='External link' rel='nofollow external'>Napster</a> and <a href='http://groups.yahoo.com/group/the_gdf/' class='bbc_url' title='External link' rel='nofollow external'>Gnutella</a>. In fact, the Internet itself can be viewed as a network of distributed, but similar, resources tied together by a common naming system supported by a hierarchical peer network of servers, the Domain Name Service (DNS).<br />
<br />
 The common distributed topologies include: Centralized, Ring, Hierarchical and Decentralized.<br />
<br />
 /reference/programming/features/distributed/image002.gif <br />
<strong class='bbc'>Centralized</strong><br />
 The most common topology we see on the Internet is centralized. This design is closely associated with the "client-server" model where a centralized server manages all resources available for client consumption. Most web sites, database applications and online games use such a model.<br />
<br />
 Pros:<br />
<br />
 <ul class='bbc'><li>Simplified administration. </li><li>Ease of maintenance. </li><li>Ease of locating resources.</li></ul> Cons:<br />
<br />
 <ul class='bbc'><li>Difficult to scale. </li><li>High cost of ownership. </li><li>Little or no redundancy.</li></ul> <br />
<strong class='bbc'>Ring</strong><br />
 /reference/programming/features/distributed/image004.gif In a typical ring topology, several identical servers are tied together in a loop-fashion. This allows a degree of scalability and provides simple load-balancing for increases in demand by clients. To facilitate this, servers implementing ring topologies are normally co-located for reliability.<br />
<br />
 Pros:<br />
<br />
 <ul class='bbc'><li>Some scalability. </li><li>Some redundancy. </li><li>Simple load-balancing.</li></ul> Cons:<br />
<br />
 <ul class='bbc'><li>Scalability limited to hardware. </li><li>Higher cost of ownership than centralized model. </li><li>Difficult to add more resources.</li></ul> <br />
<strong class='bbc'>Hierarchical</strong><br />
 /reference/programming/features/distributed/image006.gif Hierarchical topologies follow a tree-like structure where dominance is indicated by the depth at which a node or "leaf" is located. The most dominant node, called the "root", is located at the very top of the tree. Lower-level nodes generally take instruction from higher-level nodes giving a very structured form of communication and control.<br />
<br />
 Pros:<br />
<br />
 <ul class='bbc'><li>Structured communications flow. </li><li>Quick location of resources. </li><li>Resources can be in disparate locations.</li></ul> Cons:<br />
<br />
 <ul class='bbc'><li>Timeliness of information can be limiting. </li><li>Propagation of "bad" data can occur. </li><li>Difficult to extend and add new resources.</li></ul> <br />
<strong class='bbc'>Decentralized</strong><br />
 /reference/programming/features/distributed/image008.gif In a decentralized topology, all peers are equal. They most often duplicate the same resources with connections between peers unstructured and often dynamic. Decentralized applications boast to be the most scalable, but are also the most difficult to manage.<br />
<br />
 Pros:<br />
<br />
 <ul class='bbc'><li>Highly extensible and scalable. </li><li>Highly fault tolerant. </li><li>Dynamic addition of new resources.</li></ul> Cons:<br />
<br />
 <ul class='bbc'><li>Scalability overhead can be large. </li><li>Difficultly in synchronizing data and state. </li><li>Extremely difficult to manage all resources.</li></ul> <strong class='bbc'>Note:</strong> The above descriptions are very basic in nature. They are given only as a generalization for further discussion.<br />
<br />
 Most modern distributed applications take a hybrid approach by mixing two of the above common topologies. A hybrid approach aims to bridge several benefits of the combined topologies while limiting the difficulties. This approach is used in the Meesha Network implementation of distributed gaming, described below.<br />
<br />
 <br />
<strong class='bbc'>Distributed Gaming</strong><br />
 <br />
<strong class='bbc'>The First Attempt</strong><br />
 The first network games took a centralized approach. This was the most obvious choice when considering a current game design that one would like to make network-aware. The "client-server" model was well known in other software applications and so were the methods to combat latency and scalability: buy a lot of pipe and high-end servers.<br />
<br />
 For small network games, a client-server model is still a popular choice. However, this becomes quickly un-wieldy when attempting to scale to thousands or more concurrent users. Obvious bottlenecks occur and the overall game-play degrades.<br />
<br />
 <br />
<strong class='bbc'>E-commerce Similarity</strong><br />
 A similar situation occurred within e-commerce and the Web. The first approach to sell products online took a client-server model where customers interacted with one or more web servers that in turn interacted with one or more databases. The performance issues that ensued surfaced as incomplete orders, credit authorizations that "hung", and product pages that never fully displayed, to name a few.<br />
<br />
 Reliable methods were needed to scale specific "pieces" within an e-commerce site. This led to the introduction of several component architectures (including CORBA, COM and EJB) to better identify and encapsulate these pieces of functionality. This also facilitated the means to dynamically scale resources within a given server. However, scaling across server boundaries was still very difficult to accomplish and generally required that all servers were co-located for better efficiency. Without the ability to scale specific resources across a collection of servers, component architectures were limited to duplicating <strong class='bbc'><em class='bbc'>all</em></strong> resources across identical servers with the load-balancing of user requests handled by external network hardware.<br />
<br />
 A further means was needed to scale specific e-commerce resources. The ability to perform this across heterogeneous platforms was also desired. Moreover, the ability for disparate systems to interact from separate, remote locations would facilitate business-to-business (B2B) transactions between corporate partners. In the end, such facilities would help prove e-commerce as an efficient, online retail channel.<br />
<br />
 Recently, "web services" has become a popular technology to deliver such facilities. This technology enables disparate, heterogeneous systems to communicate effectively across the Internet with one another and expose internal services in a common structured language. Web services also shares many goals with peer networking. [2]<br />
<br />
 <br />
<strong class='bbc'>Distributed Gaming</strong><br />
 Online gaming can learn from the trials put through e-commerce development. The differences between the two applications can be generally boiled down to the nature of the specific resources and the timeliness of the data. Whether we talk about the state of product information in an e-commerce system or the state of the "universe" in an online game, the issues of scalability, reliability and availability are still the same.<br />
<br />
 Drawing from web services and peer networking, we can envision a model for online gaming with the following features:<br />
<br />
 <ul class='bbc'><li>Redundant, loosely-coupled, game-specific resources. </li><li>A mechanism for the discovery of these resources. </li><li>The ability to dynamically switch between resources that provide the same service or information. </li><li>A trust relationship between resources and metrics by which to measure that trust.</li></ul> To facilitate these features, we define the following:<br />
<br />
 <strong class='bbc'>The Resource:</strong> The encapsulation of a specific source of information or service particular to a game. The total extent of a game application is the summation of all unique resources. All resources share these qualities:<br />
<br />
 <ul class='bbc'><li>Uniquely identifiable. </li><li>Locatable. </li><li>Ability to communicate with other resources. </li><li>Ability to synchronize internal state with other similar resources.</li></ul> <strong class='bbc'>The Provider:</strong> A peer that provides a unique resource to consumers.<br />
<br />
 <strong class='bbc'>The Consumer:</strong> A peer that seeks service or information from another peer it considers "trustworthy" to some measurable degree. A consumer can be any peer in the network, including those that are also providers.<br />
<br />
 <strong class='bbc'>The Trusted Peer:</strong> A provider that, over time, has given a degree of consistent information or service so that it is considered relatively "trustworthy" by a specific consumer. Trust is measured by a combination of metrics that represent the reliability and availability of the information or service that the trusted peer provides to the consumer. As such, these metrics are calculated from the viewpoint of the consumer but can be shared with other consumers to build a "network of trust" amongst all consumers seeking the same resource.<br />
<br />
 <strong class='bbc'>The Registrar:</strong> A specific type of provider that manages the discovery and location of all types of resources. All providers are required to provide information to a registrar that uniquely identifies it in the network and describes the type of information or service that it provides. Registrars maintain a map of resources amongst one another so consumers have a means of discovery for specific resources and the available providers.<br />
<br />
 <strong class='bbc'>The Game Network:</strong> A network of loosely-coupled resources that collectively represent all functionality, services and information for a specific game application. The state of the game is the collective state of the individual resources for any point in time. Multiple resources exist that duplicate the same information or service. Resources can discover and locate one another through a specific resource called the Registrar. These resources can then actively communicate with one another and dynamically determine the most available and reliable resources from their unique view of the network based on a measurable trust relationship. Scalability is dynamically increased as more redundant resources are introduced to the network, are discovered by other consumers, and rise in trust value. Similarly, the game network is extended in functionality by the introduction of new types of resources.<br />
<br />
 <strong class='bbc'>The Game:</strong> An application that consists of a dynamic collection of unique resources provided by the game network. The specific resources that make up a game for an end-user can change at any time but must always provide the most reliable and most available services and information. The switching of resources must be transparent to the user. At all times the user’s view and experience of the game must be consistent and not interrupted by the switching of resources.<br />
<br />
 <br />
<strong class='bbc'>An Example</strong><br />
 Suppose we have a typical massive, multi-player, online, role-playing game (MMORPG). We can define the features and functionality of this game as a set of unique resources (<strong class='bbc'>Diagram1</strong>):<br />
<br />
 <ul class='bbc'><li><strong class='bbc'>Map System:</strong> The world in which the game takes place. </li><li><strong class='bbc'>Events System:</strong> Unique activities that are time sensitive, such as weather, changes in environment and non-player character (NPC) campaigns. </li><li><strong class='bbc'>Player System:</strong> The management of player state and related information. (Note that in this example our players make up part of this system.) </li><li><strong class='bbc'>NPC System:</strong> The management of NPC state and related information. This could include monsters, wildlife and other non-player characters. </li><li><strong class='bbc'>Time System:</strong> The global clock. A simple resource to synchronize time amongst all resources.</li></ul> With this simple set of resources, we have a representation of the majority of functionality found in today’s MMORPGs. In order for a player to enter the game, she must locate providers of these five resources. (This will require, of course, Registrar resources, as described above.)<br />
<br />
 As with other MMORPGs, we quickly realize that we must handle thousands of players, if not more. Thus, the Game Network needs to include more redundant providers in the Player System. As players come online, they will locate an available provider from the Registrar. Scaling the network to meet the demand of even more players simply requires the addition of more providers.<br />
<br />
 Similarly, the other resources must scale as demand increases. However, for simple resources, providers that also serve other, more complex resources may manage this. The Time System is a good example of this. All resources, including the Player System that represents the users themselves, can be providers of the global clock. This is a design consideration to allow the other resources a more reliable means to synchronize state amongst each other.<br />
<br />
 As a user interacts with the game application (or, rather, as the player plays the game), the supporting systems may change according to the user’s unique view of the network at specific moments in time. Indeed, the game itself may add new features and functionality as the user’s game progresses. This is perhaps the greatest feature of distributed gaming: the ability to scale and simultaneously evolve without disturbing game play. As more resources are introduced to the game, the better the game becomes.<br />
<br />
 /reference/programming/features/distributed/image010.gif<br />
Diagram1: The entire game network for our MMORPG example consists of six distinct systems containing redundant resources. Note that the players are considered part of one system.<br />
<br />
 <br />
<strong class='bbc'>The Meesha Network</strong><br />
 The Meesha Network is an implementation of distributed gaming, as described above. It presents a simple API to create game-specific resources and the game network in which they exist. Meesha facilitates all functionality and management transparently to the game application.<br />
<br />
 The Meesha Network provides the following:<br />
<br />
 <ul class='bbc'><li>Creation of resources. </li><li>Discovery of resources. </li><li>Communication between resources. </li><li>Trust metrics. </li><li>Dynamic resource switching.</li></ul> The current Meesha implementation is specific to Windows platforms. Its API is exposed as a collection of COM objects for quick and easy integration to existing game designs. A technical demo is available upon request (see "About the Author", below).<br />
<br />
 <br />
<strong class='bbc'>Demo Screenshots</strong><br />
 The current technical demo implements a single resource type: the map system. The map system tracks information regarding the position of a single terrain object. For the purposes of the demo, one local consumer and two remote providers are shown (<strong class='bbc'>Screen1</strong>).<br />
<br />
 When the demo starts, the consumer has not received information from either provider resource, thus showing the position of the terrain object incorrectly (<strong class='bbc'>Screen2</strong>). (Note: the providers are shown side-by-side for the purposes of the demo. In reality, they would serve the exact same positional data.) As the consumer receives data from one of the providers, it corrects its display of the terrain object to follow this provider (<strong class='bbc'>Screen3</strong>). The consumer will continue to follow the provider across the screen as information is received (<strong class='bbc'>Screen4</strong>). Artificial latency is introduced between the providers and the consumer so that the consumer will attempt to re-send requests that were not answered in a timely fashion (<strong class='bbc'>Screen5</strong>). When the "retries" count reaches 10, the consumer will switch from its current provider to the other provider (<strong class='bbc'>Screen6</strong>). This demonstrates the ability of the consumer (and all peers in the Meesha Network) to dynamically switch resources based on its particular view of the network.<br />
<br />
 /reference/programming/features/distributed/image011.png<br />
Screen1: The red ring indicates the "localmap" consumer. Particle effects rings indicate the "remotemap1" and "remotemap2" providers.<br />
<br />
 /reference/programming/features/distributed/image013.png<br />
Screen2: The state of "localmap" is not synchronized with any provider.<br />
<br />
 /reference/programming/features/distributed/image015.png<br />
Screen3: "Localmap" is following "remotemap1".<br />
<br />
 /reference/programming/features/distributed/image017.png<br />
Screen4: As long as responses are timely, "localmap" continues to follow "remotemap1".<br />
<br />
 /reference/programming/features/distributed/image019.png<br />
Screen5: "Localmap" re-sends several requests to "remotemap1".<br />
<br />
 /reference/programming/features/distributed/image021.png<br />
Screen6: "Localmap" switches resource providers to "remotemap2".<br />
<br />
 <br />
<strong class='bbc'>Conclusion</strong><br />
 Distributed gaming and the Meesha Network implementation have profound implications for online gaming. It is easy to imagine a highly distributed game application where the users themselves increase resource availability by becoming resource providers. (This would have the added benefit of aggregating bandwidth at the end-users!) However, traditional online games companies can also leverage the Meesha Network as a means to easily evolve existing applications in order to scale specific resources (the Player System, the Map System, etc.) and to leverage existing investments in infrastructure. Meesha is an enabling technology that is non-specific to any particular online game.<br />
<br />
 Distributed gaming provides availability, reliability and scalability to online gaming. It consists of a hybrid of peer topologies and provides a proven services model found in e-commerce. The Meesha Network implements distributed gaming in a simple API so that existing and future game applications may feature distributed gaming in their designs.<br />
<br />
 <br />
<strong class='bbc'>About the Author</strong><br />
 Omar Abdelwahed graduated from the University of Minnesota-Duluth in 1994 with a bachelor’s degree in Computer Engineering. He has worked in Information Technology since the ripe old age of 15 and wrote his first video game in 1984 (affectionately titled "Save the World From All the Rockets that Keep Appearing from the Right-Hand Side of the Screen"). Currently, Omar is a lead software engineer at Best Buy Co., Inc. where he designs and develops entertainment web sites.<br />
<br />
 Omar can be reached by e-mail at: <a href='mailto:omar.abdelwahed@bestbuy.com' title='E-mail Link' class='bbc_email'>omar.abdelwahed@bestbuy.com</a>.<br />
<br />
 <br />
<strong class='bbc'>Further Information / Endnotes</strong><br />
 [1] <a href='http://www.openp2p.com/pub/a/p2p/2001/12/14/topologies_one.html' class='bbc_url' title='External link' rel='nofollow external'>Distributed Systems Topologies: Part 1 by Nelson Minar.<br />
<br />
 </a>[2] <a href="http://www.openp2p.com/pub/a/p2p/2001/07/20/convergence.html">Convergence of Peer and Web Services by Jeff Schneider.<br />
<br />
]]></description>
		<pubDate>Sat, 31 May 2003 13:45:52 +0000</pubDate>
		<guid isPermaLink="false">e7308d3f1c68503c7b5247a10d8a2afe</guid>
	</item>
	<item>
		<title>A Win32 Approach to Multi-threaded Servers Part...</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/a-win32-approach-to-multi-threaded-servers-part-r1804</link>
		<description><![CDATA[

<p class="c1"><span class="title">A Win32 Approach to Multi-threaded Servers Part I - WinSock</span><br>
<span class="author">by <a href="mailto:cliffordr@hfx.eastlink.ca">Kurifu Roushu</a></span></p>
<p>Thanks to Smoogle for editing this article for me.</p>
<h1>Preface</h1>
<p>This article I intend to be the first of a few articles, to form a series, in which I will use to take a pretty much ground up approach to creating a multi-threading game server using Win32. Many
of you may have seen me poking around the forums in GameDev asking a few questions so that I may more readily complete this article with as much information as possible.</p>
<p>Within this series I do assume that you have a basic understanding of Win32. Some understanding of WinSock would be beneficial, however it should not be required since this is what the first part
of the article series will be covering.</p>
<p>The WinSock code in this article will be written as close to the BSD standards as I can make it, so that theoretically the code could be easily ported over to run on any Berkerly Socket Descriptor
aware operating system, such as Linux, FreeBSD, and so forth.</p>
<p>The small application source code included (<a href="1804/main.c">main.c</a>) was originally written to be compiled and use in a Linux environment with gcc. This is the machine I had at hand when
I wrote this code, and should also provide a basic overview of the differences between Win32 and Linux based socket code.</p>
<h1>Introduction</h1>
<p>One of the first things that you need to know about Windows Sockets is that there are three types of sockets that exist: blocking, non-blocking, and asynchronous. Though asynchronous and
non-blocking are sometimes seen as very similar, they are not, and shortly you will learn why.</p>
<p>Blocking sockets are what I would call your regular everyday plain old sockets. They hold one connect (just like the others), and when you make a call to recv(), send(), or accept() they will stop
the program execution and not return until in incoming connection is made, or data is sent or received. These sockets are the basis to a multi-threading server and will be what we use from this point
forth in the documentation.</p>
<p>Non-blocking sockets work in the same manner that blocking sockets do with one exception. Function such as recv(), send(), and accept() will return even if there is no information waiting and
program execution will continue normally. The problem that these sockets present is that because they may not return data, you have to keep watching them using very tight loops to actually get the
data. These loops may consume unneeded CPU cycles in your application, especially if the code is not optimized correctly.</p>
<p>And last but not least, Asynchronous sockets, which may be sometimes mistaken as non-blocking socket - though they are not - use the Windows Messaging queue to notify the application when it is ok
to send, when there is an incoming connection, and when there is incoming data. Note though that the accept(), recv(), and send() functions are in fact blocking functions and will not return until
properly executed, however since Windows should not be notifying us unless data is actually present, this does not present a problem since the data will already be there when we call them.</p>
<p>Asynchronous sockets have a particularly useful application when the program has other functions to do, such as drawing sprites, checking for other input, and so forth. There is only one catch
with asynchronous sockets, and that is that since they rely upon the Windows Messaging queue, they are also exclusive to Windows. This is the kind of socket you would want to use on the client end of
the application in most cases.</p>
<h1>Setting things up</h1>
<p>Since we will need a socket for every single client that is to connect to our machine, we will create a nice little structure to hold all of the basic client information.</p>
<blockquote>
<pre class="code">
#include <windows.h<
#include <winsock.h<

struct CLIENTS {
  bool         InUse;
  SOCKET       ClientSocket;
  Sockaddr_in  ClientAddress;
  DWORD        dwThreadID;
  HANDLE       hThreadID;
};
</pre></blockquote>
<p>In this structure we have provided InUse, to represent wether this socket ( I will refer to it as "seat" in the future) is available or not. SOCKET will be the actual socket descriptor for that
specific client, and soackaddr_in is used to hold the socket type, and address for the client. The two ThreadID variables will be used later on when creating a client thread so that we may control
the thread later on.</p>
<p>We will also create a SOCKET and sockaddr_in for the listening socket:</p>
<blockquote>
<pre class="code">
CLIENTS     Clients[ MAX_CONNECTS ];
SOCKET      ListeningSocket;
Sockaddr_in Address;
</pre></blockquote>
<h1>Initializing WinSock</h1>
<p>Unlike the BSD implementation of sockets, if we wish to use WinSock we will have to initialize and load the WinSock DLL. To do this we make a simple function like follows:</p>
<blockquote>
<pre class="code">
HRESULT InitWinSock( ){
  WSADATA  wsad;

  for( int i =3D 0; i < MAX_CONNECTS; i++ ){
    Clients[i].InUse = flase;
  }

  WSAStartup( MAKEWORD( 2, 2 ), &wsad );

  return S_OK;
}
</pre></blockquote>
<p>Essentially here what is happening is that we will create a variable wsad (of type WSADATA) to hold any information about WinSock that WSAStartup returns. From here we will cycle through all of
the client structures and set them all as available and than we make a call to WSAStartup() to initialize and load WinSock.</p>
<p>MAKEWORD( 2,2), is just another way of specifying 0x0202, which to WSAStartup means load WinSock 2.2.</p>
<p>Should WSAStartup() fail, it will return non-zero. You should implement code to handle this even and call WSACleanup() should this occure.</p>
<h1>Setting up the Listening Socket</h1>
<p>Next what we need to do is take the ListeningSocket defined above and prepare it to bind to a port and start listening for incoming connections.</p>
<blockquote>
<pre class="code">
ListeningSocket = socket( AF_INET, SOCK_STREAM, 0 );

Address.sin_family       = AF_INET;
Address.sin_port         = htons( PORT );
Address.sin_addr.s_addr  = htonl( INADDR_ANY );

bind( ListeningSocket, (LPSOCKADDR)&Address, sizeof(Address));

listen( ListeningSocket, SO_MAXCONN );
</pre></blockquote>
<p>What we did above was first set the properties of the listening socket. AF_INET pretty much means we will be using a standard TCP/IP protocol, SOCK_STREAM means that we will be using a guaranteed
TCP connection as opposed to an unstable UDP connect (SOCK_DGRAM).</p>
<p>htons() is a function that will convert a normal number into a network short number, in this case the port number that we want to server to listen on, and htonl converts a normal number to a long
network number. In this case s_addr is set to INADDR_ANY which specifies that we will listen on all interfaces. This is generally what you want to set it as.</p>
<p>bind will connect the socket to the specified port number, and listen will cause the socket to start listening for TCP_SYN packets - also known as your connection request. Note that SO_MAXCONN is
used in listen(). This will specify the maximum number of connection to enqueue at once, anything more than this amount will be denied. Generally a value between 2 and 10 should work in here in most
situations, while SO_MAXCONN is the ISP set maximum of connection requests at once.</p>
<h1>Setting up for multithreading</h1>
<p>What we will need to do next is create two functions, one of which will be used to start a client thread, and the other which will be the client thread.</p>
<blockquote>
<pre class="code">
HRESULT StartClientThread( ){
  // NO ONE ELSE CAN CONNECT UNTIL THIS THREAD IS READY
  ThreadInit = true;

  for( int i =3D 0; i < MAXCONNECTS; i++ ){
    if( Clients[ i ].InUse == true ){
      ClientID = i;
      break;
  }
}

Clients[ClientID].hThreadID = CreateThread( NULL, 0, &ClientThreadEntry, 0, 0,
                                            Clients[ClientID].dwthreadID );
</pre></blockquote>
<p>This is the code that will start the client thread. It has two variables which you will need to make global variables. ThreadInit, a bool, is used so that no one else can start a thread while we
are still retrieving information on the one that is presently starting. This variable should be initialized as false. We also have ClientID, which will be the index of the Clients array that
connecting client will use.</p>
<p>In this code we simply set ThreadInit to true, so that no one else overwrites our data before the client thread copys it, and use a for() loop to find the first available seat in which the
incoming client will sit on.</p>
<p>After this we make a call to CreateThread which will in turn pass the address of the ClientThreadEntry function which will serve as our client's thread.</p>
<blockquote>
<pre class="code">
DWORD WINAPI ClientThreadEntry( LPVOID Arg1 ){
  int       ClientNo = ClientID;
  CLIENTS   *Client = &Clients[ ClientID ];

  Client->InUse = true;

  // MOVE THE SOCKET INFORMATION FROM SOCK A TO SOCKET B
  memcpy( &Client->ClientSocket, &SinkSocket, sizeof( SinkSocket ));
  memcpy( &Client->ClientAddress, &SinkSockAddr, sizeof( SinkSockAddr ));

  // DONE .. CONTINUE NORMAL EXECUTION IN THE PARENT THREAD
  ThreadInit = false;

  return 0;
}
</pre></blockquote>
<p>This is the client thread, when the thread is started this code will be given its own point of execution and will only work with the one client that has connected.</p>
<p>I like to make things more convenient when I think of it, so I will create another Client Descriptor CLIENTS to point to the array item that this client connection sits on. I will also use
ClientNo to store the index number to that array locally, remember that before the thread was called it was stored in a global which will be overwritten for the next client that tries to connect. We
than set the client as in use using our pointer Client->InUse = true;</p>
<p>Now, before we can give control back to the parent thread to accept more connection we must copy the Socket, and sockaddr_in information. To do this we simply just perform a memcpy() on the global
instances, and copy them into the client structure variables. Now they are ready for use by the next client so we set TreadInit to false and resume normal program execution of the parent thread.</p>
<p>When the function returns, the thread itself returns with that value and terminates so within this code a loop that would consistently checks for incoming data from the client would be needed.
Once data is received, you simply check to see what is in the packet that was sent, and than make any changes that your require from that.</p>
<p>The next article will address receiving and decoding packets. I would write it with this article, but I am tired now and would like to get some of my own coding done.</p>
<h1>Conclusion</h1>
<p>With the code given above you should be able to write a basic server that will accept incoming connections and start a thread which will than copy the information into the client structure for its
own use.</p>
<p>One thing you must remember to do is to clean up all pointers, closesocket( SOCKET ), on all opened sockets, and call WSACleanup() when your server shuts down.</p>
<p>Included with this article is a little program I wrote in linux to actually test the server. It will have more use for the next article, bur should provide a great demonstration of the
Windows/Linux socket compatibilities.</p>
<p>In my next article I will address packet decoding and packet structures, as well as how to handle the different array of possible packets you could receive. I also intend to provide functioning
cleanup code, and whatever else I can think of at that time.</p>
<p>If you have any suggestions or comments, please feel free to email them to me at <a href="mailto:cliffordr@hfx.eastlink.ca">cliffordr@hfx.eastlink.ca</a>, or you can even come online on
irc.afternet.org to channel #gamedev, #necrosoft, or #Toronto and talk to me in there since I spend 98% of my internet life in there anyway.</p>

]]></description>
		<pubDate>Thu, 18 Apr 2002 21:32:30 +0000</pubDate>
		<guid isPermaLink="false">8d3b78d62523e16a1c95a545651db6bf</guid>
	</item>
	<item>
		<title>Advanced WinSock Multiplayer Game Programming:...</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/advanced-winsock-multiplayer-game-programming-r1587</link>
		<description><![CDATA[Combating lag is a major problem in multiplayer network game development. As multiplayer game developers, we always strive to make things faster, leaner and meaner to reduce lag and free up bandwidth. This is why we often forsake the reliability of TCP for the speed that UDP provides. Multicasting is yet another step in the fight against latency, carrying many promises, including the transmission of very high quality streaming digital TV over networks and in the future, the Internet. What is the magic behind multicasting and how can it be used in our games? In short, it can not only reduce server workload but is also a solution to the age old problem of players finding each other on networks without the game developer having to put up dedicated master servers, but more on that later.<br />
<br />
 Oh, and if DirectPlay uses multicasting extensively, then it's all more the reason for us to use it <img src='http://public.gamedev.net/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' />.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>The Idea Behind Multicasting</strong></span><br />
<br />
The theory goes something like this. In the most commonly used networking client-server model, when a client sends input to the server, this input updates the game state and then the server tells all the other clients about what has happened by sending the same information to all the clients:<br />
<br />
<p class='bbc_center'><a class='resized_img' rel='lightbox[f4d8edec957a4e15ab2996c2695b2faf]' id='ipb-attach-url-3655-0-60585100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3655" title="diagram1.jpg - Size: 37.5K, Downloads: 76"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-33168100-1309234085_thumb.jpg" id='ipb-attach-img-3655-0-60585100-1330207728' style='width:250;height:165' class='attach' width="250" height="165" alt="Attached Image: diagram1.jpg" /></a> </p><br />
 As you can see there is a traffic problem on the server's network connection. If, say, there were 32 players connected to the server at the time, then the same information would be sent 32 times (once to each player). If there were 20 bytes of data to be sent to each of the 32 players then 640 bytes would have to be sent through the server's network connection. If that were to happen every time any of the 32 players pressed a key or moved the mouse, a huge amount of traffic is generated. Naturally, there is no replacement for good coding practice and sending only the data that is needed, but multicasting can seriously help.<br />
<br />
 So how can multicasting help? Well, Multicasting can dramatically reduce the amount of data that needs to be sent by taking the task of packet replication away from the game server to the actual network infrastructure. In multicasting, packets can be sent to groups of network addresses, instead of individual addresses.<br />
<br />
 This is similar to the way email works - when we want to send the same email message to multiple email addresses, we don't send the message to every address from our computer. Instead we send the message once, telling the server to replicate the message to all the other addresses.<br />
<br />
<p class='bbc_center'> <a class='resized_img' rel='lightbox[f4d8edec957a4e15ab2996c2695b2faf]' id='ipb-attach-url-3656-0-60651100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3656" title="diagram2.jpg - Size: 37.95K, Downloads: 81"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-32190100-1309234107_thumb.jpg" id='ipb-attach-img-3656-0-60651100-1330207728' style='width:250;height:165' class='attach' width="250" height="165" alt="Attached Image: diagram2.jpg" /></a><br />
</p><br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>The Darker Side</strong></span><br />
<br />
Of course, there are reasons why multicasting is not commonly used:<br />
 <ul class='bbc'><li>Some ISPs and networks don't support multicasting yet. Bastards. So if you want to implement multicasting in a game, you're better off adding it as an option. Internet multicasting is rarely supported, but hopefully it will be in the future.</li><li>Multicasting only makes a worthwhile gain in performance when network data is replicated, realistically only worth bothering when there is support for more than four players.</li><li>Multicasting requires some more coding and programmers are lazy to even look into it. As you will see, in fact it requires very little additional code. The corporate "Quality Digital TV via Multicasting" idea seems to put game programmers off the subject altogether, I suspect it has something to do with hacker ethics, so long live the .org's!</li><li>The openness of multicast groups may make your packets easier to sniff. Usually UDP packets can only be intercepted between their source and destination, but now they can be captured anywhere on the network; by joining the right group, anyone can get a carbon-copy!</li></ul> <br />
<span style='font-size: 18px;'><strong class='bbc'>How Multicasting Works</strong></span><br />
<br />
You may have heard of broadcasting. Broadcasting forwards data to every address on the network. Unlike broadcasting, multicasting only forwards to those addresses who have explicitly registered interest in the data.<br />
<br />
 On an IP network supporting multicasting there are such things as multicast groups. If you want to receive multicast data packets, you must join a multicast group. Although it should be possible to send data packets to a multicast group regardless of membership, it is often better to join a group before sending to it for reasons I won't venture into. If you are a member of a group to which you are sending multicast data packets, you will receive a copy of the data packets. Also, a client will not receive all data packets from a multicast group, but only those which are sent to the port that the socket is bound to.<br />
<br />
 So a sensible idea would be for all the game clients to join a multicast group and wait for data on the same port. Then the server, by sending a single packet of data to that multicast group, would be sending to all the clients as the packets are replicated somewhere along the way.<br />
<br />
<p class='bbc_center'><a class='resized_img' rel='lightbox[f4d8edec957a4e15ab2996c2695b2faf]' id='ipb-attach-url-3657-0-60664600-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3657" title="diagram3.jpg - Size: 42.39K, Downloads: 67"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-78528700-1309234377_thumb.jpg" id='ipb-attach-img-3657-0-60664600-1330207728' style='width:250;height:165' class='attach' width="250" height="165" alt="Attached Image: diagram3.jpg" /></a></p><br />
 We've seen the light, we've seen the darkness, so let us onto the code...<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Joining a Multicast Group and Receiving Multicast Data Packets</strong></span><br />
<br />
To receive multicast packets sent to a multicast group, your game will need to join or become a member of that multicast group. To request becoming a member of a multicast group is a lot simpler than you may at first imagine. You need to first <em class='bbc'>bind()</em> your UDP socket to a local port (elementary, my dear friend):<br />
<br />
<pre class='prettyprint'>SOCKADDR_IN addrLocal;<br />// We want to use the Internet address family<br />addrLocal.sin_family = AF_INET;<br />// Use any local address<br />addrLocal.sin_addr.s_addr = INADDR_ANY;<br />// Use arbitrary port - but the same as on other clients/servers<br />addrLocal.sin_port = htons(uiPort); <br />// Bind socket to our address<br />if(SOCKET_ERROR == bind(hUDPSocket, (LPSOCKADDR)&addrLocal, <br />                        sizeof(struct sockaddr)))<br />  {cout &lt;&lt; "Euston, we have a problem";}<br />// Ready to switch to multicasting mode&#91;code&#93;And then just make a call to &#91;i&#93;setsockopt()&#91;/i&#93;, and here's a prototype for your convenience *grin*:<br /><br />&#91;code&#93;int WSAAPI setsockopt(SOCKET s, int level, int optname,<br />                      const char FAR * optval, int optlen);</pre>If you thought you were getting away with just 1 new line of code to learn, you were wrong... you're only getting away with 4 new lines =). There are special parameters to prepare for this call: <em class='bbc'>s</em> is your socket handle, <em class='bbc'>level</em> should be set to <em class='bbc'>IPPROTO_IP</em>, optname should be set to <em class='bbc'>IP_ADD_MEMBERSHIP</em> and a pointer to the <em class='bbc'>p_mreq</em> structure passed as <em class='bbc'>optval</em>, with its length in <em class='bbc'>optlen</em>. This is what the <em class='bbc'>p_mreq</em> structure looks like:<br />
<br />
 [indent]<pre class='prettyprint'>struct ip_mreq {<br />  struct in_addr imr_multiaddr;   /* multicast group to join */<br />  struct in_addr imr_interface;   /* interface to join on    */<br />}</pre>[/indent] It has 2 fields, both of them are <em class='bbc'>in_add</em> r structures: <em class='bbc'>imr_multiaddr</em> specifies the address of the multicast group to join and <em class='bbc'>imr_interface</em> specifies the local address <em class='bbc'>INADDR_ANY</em>.<br />
<br />
 There are special (Class 'D') addresses allocated for multicast groups. These are in the range from 224.0.1.0 to 239.255.255.255. You can choose an address from the range as the target multicast group to join, and set the <em class='bbc'>imr_multiaddr</em> to this address. The full <em class='bbc'>setsockopt()</em> call would look something like this:<br />
<br />
 [indent]<pre class='prettyprint'>struct ip_mreq mreq;<br />mreq.imr_multiaddr.s_addr = inet_addr("234.5.6.7");<br />mreq.imr_interface.s_addr = INADDR_ANY;<br />nRet = setsockopt(hUDPSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,<br />                  (char*)&mreq, sizeof(mreq));</pre>[/indent] And that's all there is to it, apart from a lot of error checking which I've decided to leave out for clarity (aka Laziness). The socket will now receive data packets sent to the multicast group on the specified port with calls to <em class='bbc'>recvfrom()</em>:<br />
<br />
 [indent]<pre class='prettyprint'>SOCKADDR_IN addrSrc;<br />nRet = recvfrom(hUDPSocket, (char *)&Data, sizeof(Data), 0,<br />                (struct sockaddr*)&addrSrc, sizeof(addrSrc));</pre>[/indent] When you're finished with the group and want to leave, just repeat the call with identical parameters apart from <em class='bbc'>IP_ADD_MEMBERSHIP</em> which should be replaced with <em class='bbc'>IP_DROP_MEMBERSHIP</em>.<br />
<br />
 [indent]<pre class='prettyprint'>nRet = setsockopt(hUDPSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP,<br />                  (char*)&mreq, sizeof(mreq));</pre>[/indent] Now that we can join a multicast group and receive packets sent to it, the logical thing to do is to learn how to send packets to a multicast group.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Sending Multicast Data Packets</strong></span><br />
<br />
Sending multicast data packets is accomplished with a call to <em class='bbc'>sendto()</em>, specifying a multicast group address as the destination IP address and the wanted port (on which your clients are tuned to listen for data). So there really a lot to learn apart from using the TTL (Time To Live) socket option.<br />
<br />
 All IP packets carry a TTL value to make sure that they are discarded if they don't reach a destination so they don't clog up the network. In a multicast data packet, TTL specifies how far a multicast data packet can travel:<br />
<br />
<table border="1" cellpadding="3" cellspacing="0"  width="100%"><tbody><tr><td class="tblhdr"><span style='font-size: 12px;'><strong class='bbc'>TTL  Threshold</strong></span></td><td  class="tblhdr"><strong class='bbc'><span style='font-size: 12px;'>Description</span></strong></td></tr><tr><td>TTL  equal to 0</td><td>Restricted to the same  host</td></tr><tr><td>TTL equal to  1</td><td>Restricted to the same  subnet</td></tr><tr><td>TTL equal to  32</td><td>Restricted to the same  site</td></tr><tr><td>TTL equal to  64</td><td>Restricted to the same  region</td></tr><tr><td>TTL equal to  128</td><td>Restricted to the same  continent</td></tr><tr><td>TTL equal to  255</td><td>Unrestricted in  scope</td></tr></tbody></table>  					[From MSDN, this is very rough and should not be taken literally] <br />
<br />
Multicasting is nowhere as dangerous as broadcasting in terms of unwanted traffic that it can produce but caution is advised when using some of the higher TTL values.<br />
<br />
 To set a socket's multicast TTL value, <em class='bbc'>setsockopt()</em> can be used with <em class='bbc'>IPPROTO_IP</em> as the protocol level and <em class='bbc'>IP_MULTICAST_TTL</em> as the socket option.<br />
<br />
 [indent]<pre class='prettyprint'>char TTL = 32 ; // Restrict to our school network, for example<br />setsockopt(hUDPSocket, IPPROTO_IP, IP_MULTICAST_TTL,<br />   		(char *)&TTL, sizeof(TTL));</pre>[/indent] We must also tell the system exactly which local network interface we would like to multicast on.<br />
<br />
 [indent]<pre class='prettyprint'>// Set the local interface from which multicast is to be transmitted<br />unsigned long addr = inet_addr(YOUR_IP_ADDRESS_STRING);<br />setsockopt(sSocket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&addr,<br />sizeof(addr));</pre>[/indent] Once the TTL and multicast interface are set, just <em class='bbc'>sendto()</em> away:<br />
<br />
 [indent]<pre class='prettyprint'>SOCKADDR_IN  addrDest;<br />szHi&#91;50&#93;;<br /><br />addrDest.sin_family = AF_INET;<br />// Target multicast group address<br />addrDest.sin_addr.s_addr = inet_addr("234.5.6.7");<br />// Port on which client is set to receive data packets<br />addrDest.sin_port = htons(uiPort);<br />// Something unoriginal to send<br />strcpy(szHi,"Hello Multicast Group!");<br /><br />nRet = sendto(hUDPSocket, (char *)szHi, strlen(szHi), 0,<br />              (struct sockaddr*)&addrDest, sizeof(addrDest));</pre>[/indent] We can now join multicast groups, send and receive data from them, but how do we implement multicasting as an option in our game and what would we use it for?<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Uses of Multicasting in Games</strong></span><br />
<br />
I can think of two ways straight away - one is to use it for reducing (maybe even eliminating) the amount of repeated data that a server has to send out, but another interesting use is a global server-less interface for finding other players on the network.<br />
<br />
 The scenario: there are 2 people on a large network running the same game that want to play together, but they don't know each other's IP addresses let alone the fact that the potential opponent exists. The common ways for connecting the 2 players:<br />
 <ul class='bbc'><li>The players send out a broadcast message to the entire network, however this would create huge traffic and will probably be restricted to sub networks. Broadcasting on the Internet would create an enormous amount of traffic, so it is not allowed.</li><li>The players connect to an intermediate, "known" master server IP, which tells them of each other's existence. These servers are costly to run and their uptime is often undependable.</li><li>The players go to a chatroom hoping to find other players and play together. This will not connect all the players as some may be in different chatrooms. And the process of finding someone may take a while.</li></ul> So here we are with an age old problem (how A finds B) on one hand and multicasting on the other. Multicasting groups always have the same address - a "known" address as in the case of a dedicated server, they are online 100% of the time - unlimited uptime, they don't cost anything to connect to or send information across. All game clients simply connects to a multicast group, multicast an "I want to play" message and the servers can then advertise their availability directly (instead of broadcasting, to save bandwidth) to the clients who are members of the multicast group.<br />
<br />
 Sure, there are itsy-bitsy technical problems to sort out, but the idea is cool enough. And the TTL control allows us to query within a certain range of routers (see TTL table) so we can specifically only ask to send to our LAN, or a university network, or all servers within our country to respond. Don't you think that is COOL? I sure do.<br />
<br />
 The only problem (see "The Dark Side") remains multicast support by ISP's and networks. So the best way to add multicasting to a game is still as an option (although I hope and pray that multicasting will be 100% supported in the future). But how do we integrate multicasting into our game as an option?<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Integrating Multicasting into Games</strong></span><br />
<br />
Ok then, where do we start? There are so many different types of multiplayer games that I won't even try to explain how to integrate multicasting into different types of games. Instead I'll just give a few possible ideas of solutions in a client-server relationship.<br />
<br />
 First of all, all the current network code should be kept as it is, when you add multicast support make sure you do not remove any existing code unless you really think it is necessary.<br />
<br />
 When adding multicast support, you can either do a parallel integration where multicasting runs along with existing code, or you could write two separate sets of network code and add a 'multicast on/off switch' for the user. The on/off switch would isolate servers using the other network code and add one more daunting and mysterious switch for the average newbie to get wrong. Parallel integration (bah, the things I learned in school last year) is my favorite as it will use multicasting only if it is supported and should be transparent to the user.<br />
<br />
 So let’s stick with parallel integration - in this case the normal network code runs always, but the multicasting code only runs if multicasting is supported. How do we determine if multicasting is supported? Just read the error <em class='bbc'>setsockopt()</em> gives us when trying to join a group:<br />
<br />
 [indent]<pre class='prettyprint'>nRet = setsockopt(hUDPSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,<br />                  (char*)&mreq, sizeof(mreq));<br />if(WSAESOCKTNOSUPPORT == nRet)<br />  {<br />  // Multicasting not supported. Damn.<br />  }</pre>[/indent] The client-server relationship is a game of two halves. So what if the server supports multicasting while the client does not? How does the server know which clients are covered with a single send to the multicast group and which are not? The client first determines that it does not support multicasting, then connects to the server and tells the server whether it supports multicasting. The server usually keeps a list or array of clients, to which it is easy to add an extra boolean flag:<br />
<br />
 [indent]<pre class='prettyprint'>struct Client<br />  {<br />  SOCKADDR_IN addrRemote;<br />  /* ... Game specific info here ...*/<br />  BOOL bSupportMulticast;<br />  }</pre>[/indent] The server's function to send data sends a multicast to clients who support multicasting and normal UDP datagrams to those that do not. If, however, the server itself does not support multicasting then we must use the old method. Here's a useful code snippet for a server with multicasting as an option:<br />
<br />
 [indent]<pre class='prettyprint'>int SendToAll(char *Data)<br />  {<br />  if(bServerSupportMulticast)<br />    {<br />    // First send multicast, then send individually<br />    // to those who don't support it<br />    for(int index = 0; index &lt; MAX_CLIENTS; index++)<br />    {<br />      if(Clients&#91;index&#93;.Exist && Clients&#91;index&#93;.bSupportMulticast)<br />      {<br />        // At least one client supports multicasting, so use it<br />        SendMulticast(Data, addrMulticast);<br />        break;<br />      }<br />    }<br />    for(int index = 0; index &lt; MAX_CLIENTS; index++)<br />      {<br />      if(Clients&#91;index&#93;.Exist && !Clients&#91;index&#93;.bSupportMulticast)<br />        {<br />        OldSendToClient(Data, Clients&#91;index&#93;.addrRemote);<br />        }<br />      }<br />    }<br />  else<br />    {<br />    // Use the old method all the way regardless of support<br />    // as we ourselves don't support it<br />    for(int index = 0; index &lt; MAX_CLIENTS; index++)<br />      {<br />      if(Clients&#91;index&#93;.Exist)<br />        {<br />        OldSendToClient(Data, Clients&#91;index&#93;.addrRemote);<br />        }<br />      }<br />    }<br />  }</pre>[/indent] I hope I've shed some light on multicasting and its possible uses in games. If you've found this article the least bit interesting or have a problem, drop an email to <a href='mailto:denis@voxelsoft.com' title='E-mail Link' class='bbc_email'>denis@voxelsoft.com</a>. I hope to write another article soon, but for now, Happy Multicasting!<br />
<br />
 - Denis "Voxel" Lukianov<br />
Thanks to Jan "Riva" Halfar for the wonderful diagrams.]]></description>
		<pubDate>Fri, 09 Nov 2001 01:10:37 +0000</pubDate>
		<guid isPermaLink="false">e9f85782949743dcc42079e629332b5f</guid>
	</item>
	<item>
		<title>The Universal Game-Find Server</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/the-universal-game-find-server-r1385</link>
		<description><![CDATA[

<p class="c1"><span class="title">The Universal Game-Find Server</span><br>
<span class="author">by <a href="mailto:dragonslayer_developer@hotmail.com">Chris Haag</a></span></p>
<p class="c2">Disclaimer: I am writing this article under the assumption that noone else has written one like it; I certainly have not found one. With all the people writing games today, I'm certain
the wheel has been re-invented many times over, so please e-mail me if you find another article exactly like this.</p>
<p>When I was writing Cycles3D, I realized I needed a game-find server. In haste, I wrote a server executable that ran from my own computer, but that didn't last long. It was buggy, and when I
graduated from college, I lost my dedicated connection. I got back to it later on -- thinking at the conceptual level, that is. I wanted something generic that would run with all my future games, and
adopted the idea of a generic game-find server that worked with a paradigm that is parallel to that of a DNS server, only the "domain names" would resolve to the IP addresses of games in progress.
While discussing it in a programming chat room, it was suggested that I actually use a DNS server to do it. Putting the two together, the idea of the GNS: Game Name System server, was born.</p>
<h1>What is DNS?</h1>
<p class="maintext-2 c1"><img src="/reference/programming/features/gamefind/dns1.gif" width="379" height="168"><br>
<b>Figure 1: A graphical representation of a DNS server hierarchy.</b></p>
<p>Servers on the internet are assigned names according to the Domain Name System. Each server has a special name that consists of alpha-numeric characters seperated by periods. Every part of the
name represents a part in a hierarchy of servers. For example: with clubs.yahoo.com, the top-level domain is <i>com</i>, the next level is <i>yahoo</i>, and the last level is <i>clubs</i>. When you
want to go to clubs.yahoo.com, your computer first communicates with the <i>com</i> server, which directs your computer to the <i>yahoo</i> server, which directs you to the <i>clubs</i> server. At
that point, you get the IP address of clubs.yahoo.com, and then you connect to it with your browser.</p>
<p>You'll notice that some of the shapes in the picture are doubled. This represents the fact that for every complete domain name, there can be more than one DNS server at each level. The <i>com</i>
level server, for example, has many mirrors, because it would not make sense that every computer in the world on the internet resolve IP addresses through the same server. Imagine the traffic and
resource usage it would take!!</p>
<h1>What is GNS?</h1>
<p class="maintext-2 c1"><img src="/reference/programming/features/gamefind/dns2.gif" width="336" height="223"><br>
<b>Figure 2: A graphical representation of a GNS server hierarchy.</b></p>
<p>A GNS server is a superset of the DNS server. It has all the code functionality a typical DNS server does. If you want to find Steve's Unreal Team Fortress game, you would have to resolve the
name</p>
<p class="c1">stevesgame.awesomegamenet.3_2_1.tf.unreal</p>
<p>to the IP address of his computer.</p>
<p>The top-level domains in the GNS are not <i>com</i> or <i>org</i> like with DNS, but rather, can be the names of video games: <i>Quake, Unreal,</i> or <i>Cycles3D</i>. The lower level domains
could be a variety of things, depending on the game. For popular 3D shooters, they could be a hierarchy that goes from add-on, to version, to third-party servers like <i>Awesomegamenet</i> (which is
non-existent as far as I know) or <i>BattleNet</i>. Who says this has to be written in stone, however? The top-level domains could in fact be the <i>BattleNet</i>'s and <i>GameSpy</i>'s of our day,
while game names appear at lower levels. The point I'm trying to make here is that the concept of <i>DNS</i> may not only apply to finding websites, but also, to finding video games.</p>
<p>I said earlier that the GNS server is a superset of the DNS server...what more could it do than just resolve names to IP addresses? Well, let's be creative for a moment. Who says they have to just
point to games? Why not rankings, too? Obviously, clan servers would have to join the hierarchy...and game statistics (like player count and frags) may not only be retrieved from one specific game,
but to all the games in a specific sub-domain.</p>
<p>I know what you're thinking: "Who is this guy? Why doesn't he get with the times, and use GameSpy? We already have all the technology we need to find people and games over the Internet!" Well,
you're absolutely correct. I do not know; however, how GameSpy works. Maybe it already works this way (in which case I hide behind my disclaimer). Still, I think that the development of a client and
server side package for this concept would be a great help to small time developers or individuals who can write video games, but don't want to invest a great deal of time in this particular aspect
of their games. The best part is, 90% of the GNS package has already been programmed by those who write DNS servers and clients! Now lets see if we can get them to release their source code so we can
finish the other 10% :).</p>

]]></description>
		<pubDate>Sat, 16 Jun 2001 02:36:51 +0000</pubDate>
		<guid isPermaLink="false">949694a5059302e7283073b502f094d7</guid>
	</item>
	<item>
		<title>Targeting - A variation of dead reckoning</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/targeting-a-variation-of-dead-reckoning-r1370</link>
		<description><![CDATA[<em class='bbc'> Disclaimer: I am writing this article under the assumption that no one else has written one like it; I certainly have not found one. With all the people writing games today, I'm certain the wheel has been re-invented many times over, so please e-mail me if you find another article exactly like this. </em><br />
<br />
Anyone who develops real-time network games understands the importance of keeping them in apparent synchronization without sacrificing game play. I knew this even before starting my own, at which time I looked around programming forums on the 'net for ways to do this. I was not satisfied with any existing methods. I sat down and stared at the screen for a few hours, on and off, until I came up with a method which I call <em class='bbc'>Targeting</em>.<br />
<br />
<strong class='bbc'> Targeting is a variation of dead reckoning where a remote player moves about a local player's game instance through persistent interpolation toward an uninterpolating and dynamic position.</strong><br />
<br />
 In English, this means that another player on your screen will constantly move closer and closer to where that player really claims to be at all times. We don't keep any historic information about where the player has been; nonetheless, the remote player and any projectile he launches can appear to travel in a smooth, unbroken path.<br />
<br />
 Before we go any further, let's put a picture on the blackboard so you understand why we're doing this. There are three entities in client/server based network games: You, the server, and other players.<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[6f48c86f292942b3804ca8b98446bff7]' id='ipb-attach-url-1784-0-65465900-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1784" title="anim01.gif - Size: 9.27K, Downloads: 366"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-06992400-1301972135_thumb.gif" id='ipb-attach-img-1784-0-65465900-1330207728' style='width:250;height:84' class='attach' width="250" height="84" alt="Attached Image: anim01.gif" /></a><br />
<em class='bbc'>Figure 1: The reality of network games; what everyone sees (click for animation)<br />
</em></p><br />
 In this example, you are moving your ship back and forth, left to right. If you watch closely enough, you'll see that the server is a bit lagged behind you, and that the other player is lagged behind the server. If this isn't the case, then you need to refresh the page and/or upgrade your browser <img src='http://public.gamedev.net/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' />. This is the current reality of network games. The lag is caused by <em class='bbc'>latency</em>, which is the time it takes game data to get from your computer to everyone elses. The server won't know you moved until a short period of time after you really did move. I tend to think of the game as existing in three different "time zones."<br />
<br />
 Big deal you say? Well, not when you're trying to shoot the alien!<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[6f48c86f292942b3804ca8b98446bff7]' id='ipb-attach-url-1787-0-65503100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1787" title="miss1.gif - Size: 10.58K, Downloads: 382"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-91166700-1301972135_thumb.gif" id='ipb-attach-img-1787-0-65503100-1330207728' style='width:250;height:84' class='attach' width="250" height="84" alt="Attached Image: miss1.gif" /></a><br />
<em class='bbc'>Figure 2: Latency causes the game to go in different directions for each player</em><em class='bbc'> (click for animation)</em></p><br />
 According to your instance of the game, you shot the alien right when you were directly in front of it. The thing is, the server can be a thousand miles away, so he won't know you fired until up to several milliseconds later. In some cases, it could be hundreds of milliseconds! By then, the alien will have moved past your ship on his computer! Look above and see what happens.<br />
<br />
 Ok, so let's force your laser to appear in front of the alien on the server's machine by magically telling him that is where the laser should be. Thats fine, but now look at the game:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[6f48c86f292942b3804ca8b98446bff7]' id='ipb-attach-url-1785-0-65479100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1785" title="hit1.gif - Size: 11.06K, Downloads: 369"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-35844100-1301972135_thumb.gif" id='ipb-attach-img-1785-0-65479100-1330207728' style='width:250;height:84' class='attach' width="250" height="84" alt="Attached Image: hit1.gif" /></a><br />
<em class='bbc'>Figure 3: Overly compensating for latency makes the game look bad.</em><em class='bbc'> (click for animation)</em></p><br />
 The player on the server is thinking: "Uhhhh, where did that laser come from!?," and will then proceed to throw your game away and go play Half-Life Counterstrike.<br />
<br />
 Now, let's take this from the approach of <em class='bbc'>Targeting</em>. <strong class='bbc'>A <em class='bbc'>target</em> is a structure of information that describes the state, and change of state, of an object that exists in a remote person's instance of a game.</strong> When you fire your laser, you send a packet of data to the server saying that <strong class='bbc'>A</strong>. You shot the laser, <strong class='bbc'>B. </strong>It was shot at some position in space (ox,oy) and <strong class='bbc'>C</strong> that it's moving straight up. Here's a graphical representation of that:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[6f48c86f292942b3804ca8b98446bff7]' id='ipb-attach-url-1786-0-65490100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1786" title="illus3.gif - Size: 2.34K, Downloads: 361"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-62866000-1301972135_thumb.gif" id='ipb-attach-img-1786-0-65490100-1330207728' style='width:250;height:125' class='attach' width="250" height="125" alt="Attached Image: illus3.gif" /></a><br />
<em class='bbc'>Figure 4: The target (the blue thing) has two elements: A position, and a velocity.</em></p><br />
 In this case, the <em class='bbc'>Target</em> is at (x,y) and the <em class='bbc'>Target</em> is moving straight up because the laser is moving straight up. The <em class='bbc'>Target</em> is determined by steps <strong class='bbc'>B</strong> and <strong class='bbc'>C</strong>, and one additional factor: <em class='bbc'>The measure of latency, in milliseconds, between you and the server</em> (I will discuss how to calculate that in a moment). However, to keep the game real, the laser has to come from your ship at the position we will call (ox,oy). We want the laser to converge from (ox,oy) to (x,y) every "frame" (that is, once every time your game runs a complete cycle). Because the target is moving up, <strong class='bbc'>both (ox,oy) and (x,y) will change at every frame.</strong> Here is some pseudocode:<br />
<br />
 [indent] <pre class='prettyprint'>for each frame {<br />  target.x_velocity = target.x_velocity + target.x_acceleration;<br />  target.y_velocity = target.y_velocity + target.y_acceleration;<br />  target.z_velocity = target.z_velocity + target.z_acceleration;<br /><br />  target.x_position = target.x_position + target.x_velocity;<br />  target.y_position = target.y_position + target.y_velocity;<br />  target.z_position = target.z_position + target.z_velocity;<br /><br />  laser.x = (laser.x + target.x_position) / 2;<br />  laser.y = (laser.y + target.y_position) / 2;<br />  laser.z = (laser.z + target.z_position) / 2;<br />}</pre><br />
[/indent] And here's how it looks:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[6f48c86f292942b3804ca8b98446bff7]' id='ipb-attach-url-1788-0-65514100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1788" title="targ.gif - Size: 11.05K, Downloads: 343"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-18616700-1301972136_thumb.gif" id='ipb-attach-img-1788-0-65514100-1330207728' style='width:250;height:84' class='attach' width="250" height="84" alt="Attached Image: targ.gif" /></a><br />
<em class='bbc'>Figure 5: The server and other clients can calculate where the laser is on your screen (the target), but rather than just placing it there, it makes the laser quickly converge to that target. This makes the game run more smoothly for everybody.</em><em class='bbc'> (click for animation)</em></p><br />
 The animation is particularly slow because I want you to study this very closely and carefully. Notice in the frame after you fired your laser, the target appeared for the server in the place that the laser is on your screen...yet, the laser on the server itself appeared at (ox,oy), which is the same placed it appeared for you when you shot it. In the following frame, the target is in approximately the same place on all three machines. Remember, we account for the position, velocity, and latency between you and another machine to figure out where the target should be on that other machine. Because of targeting, the laser on the server moves <em class='bbc'>faster</em> toward the alien than it does on player 1, and <em class='bbc'>faster still</em> on other client machines. The animation that shows targeting at work isn't the best example to explain targeting, but it certainly does a better job keeping the game reasonable than the two animations before it.<br />
<br />
 Now, you might think that interpolating by half in that pseudocode I gave you makes the laser move too quick to be natural. Well, this doesn't have to be the case. You can also try other ways, like this:<br />
<br />
 [indent] <pre class='prettyprint'>laser.x = (laser.x * 99 + target.x_position) / 100;<br />laser.y = (laser.y * 99 + target.y_position) / 100;<br />laser.z = (laser.z * 99 + target.z_position) / 100;</pre><br />
[/indent] So, how do you figure out the measure of latency, and where the target should be as a result of latency? Every PC you will probably ever buy comes with an internal timer that counts the number of milliseconds since your computer booted up. The Windows API function to get this number, in units of milliseconds, is called GetTickCount(). Other OS's have other related functions. To calculate latency from computer <strong class='bbc'>A</strong> to computer <strong class='bbc'>B</strong>, computer <strong class='bbc'>A</strong> should send computer <strong class='bbc'>B</strong> a special packet that, in effect, means "Send me this packet back immediately after you get it." Just before sending it, computer <strong class='bbc'>A</strong> should call GetTickCount, and store that return value locally. When computer <strong class='bbc'>B</strong> gets the packet, it will send it right back to computer <strong class='bbc'>A</strong>. When computer <strong class='bbc'>A</strong> gets it back, it should call GetTickCount again, subtract the return value by the locally stored return value, and divide the result by 2. This will give computer <strong class='bbc'>A</strong> the approximate number of milliseconds it takes to get data to computer <strong class='bbc'>B</strong>. In this example, computer <strong class='bbc'>A</strong> is the server, and computer <strong class='bbc'>A</strong> does this latency measuring every couple of seconds, regardless of when or how often you send packets to him. Back to the immediate case study: Since the laser will move a certain distance over a certain amount of time, he can calculate the approximate distance the laser has travelled between the time you fired it, and the time he got it. Since he will then know the distance travelled, he can figure out where the target should be by displacing it by that distance.<br />
<br />
 Well this is all nice and neat, but there's one little problem: What if the laser is still too slow, and the alien does not explode for the server or the other players? Worse yet, what if there's another alien between the player and the first alien? The player thinks he can wipe out both with the same travelling laser, but the server doesn't, because the laser travels too quickly on his end. There are two ways of dealing with this:<br />
<br />
1: Tell the server you took out that other alien.<br />
<br />
 If you tell the server which aliens you take out. The server will dismiss the disappearing aliens as something done "because of latency," or the laser apparently grazing the alien ship. The only problem with that is if a no-good-nik figures out how you do this, that person can cheat all the way up to the grand high score!!!<br />
<br />
2: Do nothing and dismiss the problem as caused by lag.<br />
<br />
 With this thinking, the server is the dictator of what's really going on in everyone's game. Clients won't be able to cheat, but the game will seem less realistic and more frustrating, because you could have sworn you blasted those pesky aliens!<br />
<br />
 I really hope this puts <em class='bbc'>Targeting</em> in perspective for you. I did a quick implementation of it in one of my projects; and in testing, it has proven to work better than I had hoped, even on a 28.8 connection! If you use this technique in your game, drop me a line. I'd like to know how it turns out.]]></description>
		<pubDate>Thu, 17 May 2001 10:26:13 +0000</pubDate>
		<guid isPermaLink="false">80e4c54699b5b8cf8c67dd496909fceb</guid>
	</item>
	<item>
		<title>Multi-User Chat Client and Server</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/multi-user-chat-client-and-server-r1314</link>
		<description><![CDATA[Ok gang, here we are again with another interesting and unusual little project. In this article we'll discuss and build a simple chat server and client. The language we'll use will be VB. The reason for this is the very nice Winsock control that VB has. It allows us to code all the functionality and cover the concepts involved in multi-chat sessions without getting too confused in the actual implementation.<br />
<br />
 I've done a little investigation on the web and as it turns out it's very easy to find applications which describe client server interaction between a single client and single server. It's NOT so easy to find examples of chat applications that cater for MULTIPLE connections to the same machine. I'm talking specifically now about CHAT applications. What's the point of building a communication application if only 2 people can communicate. We want EVERYONE involved. So I decided to throw some code together to see what's involved in building this thing.<br />
<br />
 What's a chat application? Well it can be many things. When I think of a chat I think of Yahoo Messenger, AOL instant messenger or IRC. For anyone who's used NetMeeting you'll know you can also draw, type etc and send information such as files back and forward. That's all pretty advanced but built around a few simple concepts. For our purposes I'll try to keep things simple and just deal with text. Later on we'll discuss how you'd expand the applications we're going to build here to incorporate more advanced exchanges such as drawings etc.. As with all the Cornflake Articles, this project should lay the ground work for greater things to come. When you're done reading this be sure to send me some feedback on it. I'd love to hear how I can improve my writing style or explanations etc. Thanks now let's get going.<br />
<br />
 First of all we're going to need a strategy as to how we want communications to flow. I've already mentioned the words client and server but let's define those a little better.<br />
<br />
 The client is the application that the users' will use to connect to the server. The server is the application that will host the chat session and that all users will connect to. The communication will run through the system like so:<br />
<br />
<p class='bbc_center'><a class='resized_img' rel='lightbox[189c166d427444658c98fcbd4861d7d1]' id='ipb-attach-url-3381-0-68554800-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3381" title="chat_1.gif - Size: 2.43K, Downloads: 75"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-98993800-1308332038_thumb.gif" id='ipb-attach-img-3381-0-68554800-1330207728' style='width:200;height:150' class='attach' width="200" height="150" alt="Attached Image: chat_1.gif" /></a> </p><br />
 In our application our server will have 1 connection for itself. This connection will be the socket for all other clients to "plug-into" or connect to. Woah, what's a socket?<br />
<br />
 A socket is a method of connecting to a physical machine through it's network connection. We need an IP address and a Port number on that IP address. Ports are important in that certain things such as firewalls, routers and switches all can block or allow traffic on certain ports. For instance most webservers are hosted on port 80 of whatever machine they're running on. This doesn't have to be the case though, a webserver could run on any port so long as it's available. And that's the key word here, "available". Similarly, we'll need to chose a port to host our server on and ensure no other application is using it. For that reason I won't chose port 80, I'll pick a random port (1212). How do I know that's available? Answer: I don't until I try to start up the server I'm going to build. There's a virtually infinite number of ports I can pick so if this one is not available, I'll just pick another.<br />
<br />
 First we need to add the Winsock control to our list of components. Click "Project->Components" and select "Microsoft Winsock Control 6.0" from the list. That should add the following control to your toolbox:<br />
<br />
<p class='bbc_center'><a class='resized_img' rel='lightbox[189c166d427444658c98fcbd4861d7d1]' id='ipb-attach-url-3382-0-68568100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3382" title="chat_5.gif - Size: 4.25K, Downloads: 69"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-09291600-1308332071_thumb.gif" id='ipb-attach-img-3382-0-68568100-1330207728' style='width:78;height:200' class='attach' width="78" height="200" alt="Attached Image: chat_5.gif" /></a></p><br />
 We'll use three forms in this project. The client, the server and a simple loading form. We'll create all forms and controls right now so that we can then concentrate on the code instead of the GUI.<br />
<br />
<p class='bbc_center'><a class='resized_img' rel='lightbox[189c166d427444658c98fcbd4861d7d1]' id='ipb-attach-url-3383-0-68580100-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3383" title="chat_2.gif - Size: 6.75K, Downloads: 61"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-64115200-1308332090_thumb.gif" id='ipb-attach-img-3383-0-68580100-1330207728' style='width:185;height:200' class='attach' width="185" height="200" alt="Attached Image: chat_2.gif" /></a><br />
<a class='resized_img' rel='lightbox[189c166d427444658c98fcbd4861d7d1]' id='ipb-attach-url-3384-0-68593400-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3384" title="chat_3.gif - Size: 8.5K, Downloads: 63"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-76186100-1308332103_thumb.gif" id='ipb-attach-img-3384-0-68593400-1330207728' style='width:228;height:200' class='attach' width="228" height="200" alt="Attached Image: chat_3.gif" /></a><br />
<a class='resized_img' rel='lightbox[189c166d427444658c98fcbd4861d7d1]' id='ipb-attach-url-3385-0-68605700-1330207728' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3385" title="chat_4.gif - Size: 5.28K, Downloads: 57"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-21176700-1308332117_thumb.gif" id='ipb-attach-img-3385-0-68605700-1330207728' style='width:250;height:161' class='attach' width="250" height="161" alt="Attached Image: chat_4.gif" /></a><br />
</p><br />
 My forms look like this but you can arrange them anyway you want. Notice the placement of the Winsock controls on the Server and the Clients. Make sure you create a control array for the Winsock control onthe server. Do this by typing "0" in the "index" field of the Server Winsock Control properties.<br />
<br />
 The code for the startup form is really simple. It just sets the IP address and port for the server or client to listen on or connect to. It then shows the client or server depending on the button the users' pressed. It looks like this:<br />
<br />
 [indent]<pre class='prettyprint'>Option Explicit<br />Private Sub SetAddress()<br />  gPort = txtPort.Text<br />  gIPAddress = txtIPAddress.Text<br />End Sub<br /><br />Private Sub cmdClient_Click()<br />  Call SetAddress<br />  frmClient.Show<br />  Unload Me<br />End Sub<br /><br />Private Sub cmdServer_Click()<br />  Call SetAddress<br />  frmServer.Show<br />  Unload Me<br />End Sub</pre>[/indent] Let's note here that I'm using Option Explicit.<br />
<br />
 The first thing we're going to do is start our server Listening. We'll do this in the Form load event. Our server is going to listen on a specific port for our clients who want to connect. Here's the code for that:<br />
<br />
 [indent]<pre class='prettyprint'>Private Sub Form_Load()<br />  ' Only connection(0) listens, all others are connections<br />  sktConnection(0).Close<br />  sktConnection(0).LocalPort = gPort<br />  sktConnection(0).Listen<br />  ReDim gHandles(1) As String<br />  gHandles(0) = "Cornflake Server"<br />  AddToServerLog ("Server is Listening on port " & gPort)<br />End Sub</pre>[/indent] Ok so let's assume a connection is requested. For this we'll need to code the ConnectionRequest event. The most interesting and difficult thing to get right when coding any kind of network application is the handshake. Just as you'd shake someone's hand when you meet them in the street, our client must shake hands with the server to introduce itself. When our client says hello, we'll say hello back and ask the user to tell us what their name or "handle" is. We'll also do the following:<br />
<br />
 a) create an additional winsock control in the server<br />
b) assign it a random port (since it can't share the same port as the server) and<br />
c) accept the new connection on that control.<br />
d) We'll also assign a "handle" to that user, add them to the listed connections on the server.<br />
<br />
 We do this by putting the following code in the connection request event.<br />
<br />
 [indent]<pre class='prettyprint'>Private Sub sktConnection_ConnectionRequest(Index As Integer, ByVal requestID As Long)<br />  ' Now accept the new connection<br />  'A connection was requested from the server.<br />  Dim i As Integer<br />  Dim iConnection As Integer<br />  'Make sure this is control 0 in the array.<br />  'This is the only one that can accept connections.<br />  If Index = 0 Then<br /><br />	'Search for available Winsock control.<br />	For i = 1 To gNumConnections<br />  	If sktConnection(i).State = sckClosed Then<br />    	iConnection = i<br />    	Exit For<br />  	End If<br />	Next i<br /><br />	'If none was found, create a new one.<br />	If iConnection = 0 Then<br /><br />  	' Tell the world there's a new connection<br />  	gNumConnections = gNumConnections + 1<br /><br />  	'Load a new Winsock control for this connection.<br />  	Load sktConnection(gNumConnections)<br /><br />  	' This connection needs a handle<br />  	ReDim Preserve gHandles(gNumConnections) As String<br />  	ReDim Preserve gSentYN(gNumConnections) As Boolean<br />  	ReDim Preserve gMessages(gNumConnections) As String<br /><br />  	' Catch this user up on the previous conversation<br />  	' This way they don't get resent the chat session to date<br />  	gMessages(gNumConnections) = gTotalincoming<br /><br />  	' set their handle<br />  	gHandles(gNumConnections) = "unknown"<br /><br />  	' Add to the servers connections<br />  	lblActiveConnections.Caption = gNumConnections & " Active Connections"<br />  	iConnection = gNumConnections<br />	End If<br /><br />	'Set port for this control to 0. (Randomly assigns an available port.)<br />	sktConnection(iConnection).LocalPort = 0<br /><br />	'Have this control accept the connection.<br />	sktConnection(iConnection).Accept requestID<br /><br />	' Send the welcome message<br />	sktConnection(iConnection).SendData "Welcome to the CornflakeZone, enter your handle"<br />  End If<br /><br />End Sub</pre>[/indent] Ok so now the users' received a request to input their username/handle. Let's imagine that the client did that. We'd get a DataArrival event triggered on that client's server side winsock control. VB tells us which control this is by filling in the "index" parameter for us. To complete the "handshake", I've added some logic to state that if the user's handle is unknown then the data arriving must be their handle so assign it.<br />
<br />
 If the handle is assigned then the data arriving must be a part of the conversation so we add it to the global record of the conversation. I've coded some simple functions to do these tasks for me. Here's the DataArrival code.<br />
<br />
 [indent]<pre class='prettyprint'>Private Sub sktConnection_DataArrival(Index As Integer, ByVal bytesTotal As Long)<br />  'Data has arrived at the server from an open connection.<br />  Dim newdata As String<br /><br />  'Get the data.<br />	sktConnection(Index).GetData newdata<br /><br />  If gHandles(Index) = "unknown" Then<br /><br />	' Store it internally<br />	gHandles(Index) = newdata<br /><br />	' Announce the new arrival<br />	AddToTotalIncoming (newdata & " just joined")<br />  Else<br />	'Pass the index of the connection from which the data came.<br />	AddToTotalIncoming (gHandles(Index) & ":: " & newdata)<br />  End If<br />End Sub</pre>[/indent] Ok, it's time to complete the server side code. Let's review. We have a way for the users to connect, we have a way for the server to accept data. We don't have a way to transmit the conversation to the users. That's what we'll code next. You saw in the form screen shots that we added a timer to the server. Double click on that control to create it's interval event. The server's responsibility is to transmit the conversation to the clients.<br />
<br />
 You might have noticed me referring to the "global record of the conversation". What I mean by this is that the server maintains the conversation to date. It would be inefficient of us to send the entire conversation to EVERY client EVERY time there's an update. That's just silly. What makes more sense is that if we just send the differences in the conversation to the client. We maintain a copy of the conversation that's been sent to each client so we can determine what the differences are for that client. I do this with the "Left()" function.<br />
<br />
 We'll send the conversation updates one at a time to each client. Every time the timer fires, we send one of the clients' the latest conversation updates. Let's maintain an array of "sent YN" flags to help us figure out which clients need an update. The timer function will fire each 100 or so milliseconds so a 10 user session will experience 1 second total lag time. Not bad for a homegrown solution. You can play around with the 100 milliseconds to find the value that works best for you.<br />
<br />
 Take a look at the code for the timer function.<br />
<br />
 [indent]<pre class='prettyprint'>Private Sub tmServerTimer_Timer()<br />  txtTotalIncoming.Text = gTotalincoming<br />  'Send the new data to the group<br />  Call BroadcastMessage<br />End Sub<br /><br />Private Sub BroadcastMessage()<br />  Dim i<br />  Dim myMessage As String<br />  Dim conn_index As Integer<br /><br />  ' Set the default connection index<br />  conn_index = -1<br /><br />  ' Loop through all connections excluding the servers<br />  ' Hence we start at 1<br />  For i = 1 To gNumConnections<br />	' if this connection has not had an update then<br />	If gSentYN(i) = False And sktConnection(i).State = sckConnected Then<br />  	' Get the message we need to deliver<br />  	myMessage = Left(gTotalincoming, Len(gTotalincoming) - Len(gMessages(i)))<br />  	' update the message store for this user<br />  	gMessages(i) = gTotalincoming<br />  	' Get the index of this connection<br />  	conn_index = i<br />  	Exit For<br />	End If<br />  Next i<br /><br />  ' This is so we know to<br />  ' send the data to everyone<br />  If conn_index = -1 Then<br />	For i = 1 To gNumConnections<br />  	gSentYN(i) = False<br />	Next<br />  End If<br /><br />  If conn_index &gt; -1 Then<br />	' check the connection's open<br />	If sktConnection(conn_index).State = sckConnected Then<br />  	' send the data<br />  	sktConnection(conn_index).SendData myMessage<br />  	'signal that we've sent to this user<br />  	gSentYN(conn_index) = True<br />	End If<br />  End If<br /><br />End Sub</pre><br />
[/indent]  Ok, let's turn our attention to the client. This a much simpler little app. It handles the other side of the handshake and also accepts data and displays the chat session to the user. I've added a little button to re-connect if we'd like.<br />
<br />
 [indent]<pre class='prettyprint'>Private Sub sktClient_DataArrival(ByVal bytesTotal As Long)<br />  Dim newdata As String<br />  ' Get the arriving data and print it out.<br />  sktClient.GetData newdata<br /><br />  ' add the data to the output<br />  txtOutput.Text = newdata & txtOutput.Text<br />End Sub<br /><br />Private Sub sktClient_Error(ByVal Number As Integer, Description As String,<br />                        	ByVal Scode As Long, ByVal Source As String,<br />                        	ByVal HelpFile As String, ByVal HelpContext As Long,<br />                        	CancelDisplay As Boolean)<br />  ' This should handle any winsock errors.<br />  Call AddToOutput("Error: " & Description)<br />End Sub</pre>[/indent] Ok, that's it. If you'd like to test the application just download it and give it a shot. What's that you say? Only have one computer? That's ok, just type in localhost or 127.0.0.1. That'll connect the client to the server with both running on the same machine.<br />
<br />
 I hope you liked this tut and maybe learned a thing or two. I know I did. I didn't implement very much error checking in this app but you can easily add this and I felt it would get in the way of the code.<br />
<br />
 We implemented this in VB to keep things simple. Now that you understand how the multi-user thing works you're ready to move onto more challenging applications. Try a multi-user drawing session with a picture control. This could easily be achieved by sending the users' mouse coordinates instead of the text messages. You could then have the clients' draw what the other users are drawing! Now THAT's communicating.<br />
<br />
 If you'd like a REAL challenge try creating a COM object to wrap up the winsock object in VC++ (see last tutorial). I've already done this in VC++ and will post it in a couple of days. I do most of my coding in C++ and just found it more useful to implement the C++ object. As always, send me feedback on this article.]]></description>
		<pubDate>Thu, 01 Mar 2001 13:08:46 +0000</pubDate>
		<guid isPermaLink="false">1a47e38c424a51aba827f45d77a438b1</guid>
	</item>
	<item>
		<title>Programming with Asynchronous Sockets</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/programming-with-asynchronous-sockets-r1297</link>
		<description><![CDATA[<span style='font-size: 18px;'><strong class='bbc'>Introduction</strong></span><br />
<br />
Hello again. It’s been a while – I’ve been keeping myself quite busy with studies, work, school, and more. Ugh. But I saw a post on the boards asking for a DirectPlay or WinSock tutorial so here I am. I had to speed learn (is that even a term?) WinSock for work so we could develop a (big word here) multiplexing program for DSL modems. Blah – that got canceled. So here I am with all this knowledge and nothing to do with it – except share it, of course.<br />
<br />
 This article is written about a topic I only recently came to fully understand. It’s kinda confusing at first, but I had to rely on these stinking textbook-like books that gave no explanations whatsoever. Hopefully I can help save you from having to learn this way and then reduce yourself to begging for help and understanding from the boards. Anyway enough friggin talk – I have work to do after this. Now I have to learn (well, understand) Java in three days. Good grief. What do these people think I am, Superman? Hey I kinda like that...<br />
<br />
 This article assumes you have prior experience in WinSock programming – this article does not cover the basic WinSock conventions used within.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Asynchronous != Non-Blocking</strong></span><br />
<br />
Since you are just learning this, I will assume that up till now you have been using blocking sockets. With that in mind, I will assume that you may have toyed around with non-blocking sockets. What’s the difference? A socket that is blocked sends out a call and then <em class='bbc'>waits</em> for an answer. A non-blocking socket sends out a call and the program execution <em class='bbc'>continues</em>. This is exactly what asynchronous sockets do. However, there is a major difference.<br />
<br />
 When using non-blocking sockets, you have to continually poll the socket to see whether or not you have any actions that need to be performed. These actions can include sending and receiving data, establishing a connection, sending back a response to a connection request, etc. Non-blocking sockets have the advantage in that they allow normal program execution to continue – meaning you can process data while waiting for more to come in. This immediately makes them superior to blocking sockets in many cases (but not all).<br />
<br />
 However, asynchronous sockets take polling to a new level – they do it for you. This means that you can focus on other things while WinSock keeps watch over your sockets. (Sounds better than non-blocking sockets eh? Not always, as you’ll soon see.) So how does it do this? Well, um – I kinda like don’t really know, sorry. I do know it calls a library and that creates a thread or something and, and – well I <em class='bbc'>can</em> tell you how you are <em class='bbc'>notified</em>, even if I can’t tell you how it knows to notify you. J Had ya going there, didn’t I?<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Windows Socket Messages</strong></span><br />
<br />
That’s right – read it and weep. Hope you weren’t planning on a nice simple console app there, bucko. This requires a nice spiffy Win32 app, and nothing less. If you don’t know how to create a Win32 app (namely, a window, a message handler, and a main loop) then I can suggest the first part of <a href='http://www.gamedev.net/reference/articles/article1229.asp' class='bbc_url' title=''>Game Programming Genesis</a>, by that cool dude Ironblayde, which explains all you need to know that will get you started. Once you’re done reading that, get yourself back in here and keep going!<br />
<br />
 For those of you in the know, this is the one major advantage asynchronous has over non-blocking sockets. Of course, this can also give non-blocking sockets an advantage when you want to design a simple console app. Non-blocking sockets can be used in console apps, asynchronous sockets cannot.<br />
<br />
 But I still haven’t gotten to the topic of this section yet! Socket Messages – right. WinSock makes use of the Windows message queue in order to notify you when socket events take place. These are the events that WinSock can generate for you:<br />
 <ul class='bbc'><li><strong class='bbc'>FD_READ</strong>: This message indicates that you have just received data, and you must use the <em class='bbc'>recv()</em> function to get it.</li><li><strong class='bbc'>FD_WRITE</strong>: This means that there is room in the buffer to send, and we must send using the <em class='bbc'>send()</em> function.</li><li><strong class='bbc'>FD_CONNECT</strong>: <em class='bbc'>Used only by the client program</em>. This message indicates that the server has received the connection request and has accepted.</li><li><strong class='bbc'>FD_ACCEPT</strong>: <em class='bbc'>Used only by the server program</em>. This message indicates the receipt of the <em class='bbc'>connect()</em> request and you must send back an <em class='bbc'>accept()</em>.</li><li><strong class='bbc'>FD_CLOSE</strong>: This message indicates that the other side’s socket has shut down. This can be for several reasons.</li></ul> These five events (which are piggybacked on a message, as we’ll soon see) are all you need to manage your connections. I say connections, plural, because the beauty of this setup is that each message has the socket instance that called it stored in its wParam field. This means you can manage multiple connections with only one FD_READ or FD_WRITE message! I’ll point this out a little later.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Setting Up the Asynchronous Sockets</strong></span><br />
<br />
It’s not as hard as you may think. All it takes is for you to create the socket and then make the call to <em class='bbc'>WSAAsyncSelect()</em>, whose definition is shown below.<br />
<br />
 [indent]<pre class='prettyprint'>int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND, hwnd, unsigned int wMsg, long lEvent);</pre>[/indent] And here we have the parameter explanations.<br />
 <ul class='bbc'><li>s – the socket instance for which we want to enable event notification.</li><li>hwnd – identifies the window to which the messages will be posted, since WinSock uses <em class='bbc'>PostMessage()</em> to get the notification to you (hey, now we know how it does it!).</li><li>wMsg – the message type for the notification message(s).</li><li>lEvent – a bit mask identifying the events for which we want notification. Ex: FD_READ | RD_WRITE | FD_CONNECT.</li></ul> Now then! We know how to do it, so let’s do it already. Below is a short code segment involving creating a socket and making it asynchronous, first for a client, then for a server.<br />
<br />
 [indent]<pre class='prettyprint'>// the message we'll use for our async notification<br />#define WM_WSAASYNC (WM_USER +5)<br /><br />// create and test the socket<br />Port = socket(AF_INET, SOCK_STREAM, 0);<br />if (Port == INVALID_SOCKET)<br />  return(FALSE);<br /><br />// make the socket asynchronous and notify of read, write, connect and close events<br />// this is the client socket<br />WSAAsyncSelect(Port, hwnd, WM_WSAASYNC, FD_WRITE &#124; FD_CONNECT &#124;<br />                                    	FD_READ &#124; FD_CLOSE);<br /><br />// make the socket asynchronous and notify of read, write, accept and close events<br />// this is the server socket<br />WSAAsyncSelect(Port, hwnd, WM_WSAASYNC, FD_READ &#124; FD_WRITE &#124;<br />                                    	FD_ACCEPT &#124; FD_CLOSE);</pre>[/indent] Of course, we wouldn’t put the client and server sockets in the same app, I’m just trying to save space here. Now, take note because this is important: <em class='bbc'>You cannot perform any actions on the socket until you have declared it asynchronous</em>. Why? Let’s say you create the socket and then <em class='bbc'>send()</em> something off quick quick. Well congratulations, you just made it a blocking socket, and now your program is hung up waiting for the <em class='bbc'>send()</em> to complete. Oh yes, you can still change it to asynchronous with <em class='bbc'>WSAAsyncSelect()</em> it’s just that it’s going to cause some problems stopping execution like that.<br />
<br />
 Also notice I had to create a custom message called WM_WSAASYNC. I did this using one of Windows’ custom messages. Nothing big or worth explaining – just follow my lead. By the way, you can call this message whatever the hell you want, it doesn’t have to be WM_WSAASYNC. (Although keeping the WM_ part would be nice for people reading your code)<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Handling Notification Messages</strong></span><br />
<br />
Notification Messages is really a misleading term. In reality, WinSock only generates one message that it posts to the queue, and attached to it is the event that occurred. This is shown by the example below.<br />
<br />
 [indent]<pre class='prettyprint'>switch(msg)<br />{<br />case WM_WSAASYNC:<br />  {<br />	// what word?<br />	switch(WSAGETSELECTEVENT(lParam))<br />	{<br />	case FD_ACCEPT:<br />  	{<br />    	// check for an error<br />    	if (!WSAGETSELECTERROR(lParam))<br />      	return(FALSE);<br />    	// process message<br />    	sAccept =  accept(wParam, NULL, NULL);<br />      	return(0);<br />  	}<br />	}<br />  }<br />}</pre>[/indent] Whoa! Talk about nests! And what are all these macros doing? LParam and wParam? What the heck? Let’s now take a look at the notification message structure<br />
<br />
<table width="80%" border="1" cellpadding="3" cellspacing="0"><tbody><tr bgcolor="#666699"><td width="22%" align="center"><font color="white"><b>WParam</b></font></td><td colspan="2" width="78%" align="center"><font color="white"><b>lParam</b></font></td></tr><tr><td> </td><td align="center">HIWORD<br>WSAGETSELECTERROR()</td><td align="center">LOWORD<br>WSAGETSELECTEVENT()</td></tr><tr><td valign="MIDDLE" align="center">socket instance</td><td>0 if successful, else an error code value that can be called for using WSAGetLastError()</td><td>WinSock event such as FD_READ, FD_WRITE, FD_CLOSE, etc.</td></tr></tbody></table>Ahhh, now it’s beginning to make some sense. Let’s cover where each parameter plays its part. We’ll start with wParam. Where is it? Right here:<br />
<br />
 [indent]<pre class='prettyprint'>...<br />sAccept = accept(wParam, NULL, NULL);<br />...</pre>[/indent] And here’s what I was telling you earlier. Notice I used the variable wParam in place of the socket instance. Why? So that if I had more than one socket (s1 and s2) I could use the <em class='bbc'>same message</em> for both. So whichever socket invokes the message is passed along with it. For instance, say it was s2 that needs to receive data. Well instead of having a switch statement inside the message handler to decide which socket to place in the <em class='bbc'>accept()</em> call, I just use wParam. Translation:<br />
<br />
 [indent]<pre class='prettyprint'>sAccept = accept(wParam, NULL, NULL);</pre>[/indent] is equal to<br />
<br />
 [indent]<pre class='prettyprint'>sAccept = accept(s2, NULL, NULL);</pre>[/indent] Now that is cool. Saves you the time and the trouble now doesn’t it? I know I probably repeated myself a bit there but it’s an important point to remember and understand because it’s very useful, as you can see.<br />
<br />
 Now then, lParam is no more complicated. But there is a difference. The lParam variable has a high field and a low field, and both fields can be set to separate values. Normally we would extract these with the Windows’ API HIWORD() and LOWORD() macros. But Winsock makes our lives even easier and has two of its own macros, WSAGETSELECTEVENT() and WSAGETSELECTERROR(). These do the exact same thing as the Windows’ macros, except they relieve us of the need to remember which field holds what. If you look back up at the example above, you can see how both macros are used. The WSAGETSELECTEVENT() is your ticket to figuring out just what WinSock event was triggered. Here is the full case statement inside the WM_WSAASYNC message handler:<br />
<br />
 [indent]<pre class='prettyprint'>switch(WSAGETSELECTEVENT(lParam))<br />{<br />case FD_READ:<br />  {<br />  } break;<br />case FD_WRITE:<br />  {<br />  } break;<br />case FD_CONNECT:<br />// 	or<br />case FD_ACCEPT:<br />  {<br />  } break;<br />case FD_CLOSE:<br />  {<br />  } break;<br />}</pre>[/indent] Hope I didn’t trip you up with the FD_CONNECT and the FD_ACCEPT events – just remember that they will always depend on whether it’s the server or the client.<br />
<br />
 And finally we have the WSAGETSELECTERROR() macro, which we can use to see if an error has occurred before we decide to do anything. Usually this is not necessary, but there is one good time to error check – and that’s when the FD_CLOSE event is called. As I said earlier, there are many reasons a socket could be shut down. Here are the error codes:<br />
 <ul class='bbc'><li>0 = either the other side did a graceful close or did a <em class='bbc'>shutdown()</em> for send. Either way there was no real error.</li><li>WSACONNRESET = the other side did a <em class='bbc'>closesocket()</em> with reset close behavior.</li><li>WSACONNABORTED = the connection may have timed out. This is an abrupt abort and could even be from the user just quitting.</li><li>WSANETDOWN = network code has completely failed, which means you’re in trouble J</li></ul> It’s always best to check for these error codes when processing an FD_CLOSE event to determine just what went wrong. All other times you should just use the WSAGetLastError() function to determine what went bad.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Shaking Hands – Connecting and Accepting</strong></span><br />
<br />
Now the fun begins. We are going to place a call to <em class='bbc'>connect()</em> with the client app, send an <em class='bbc'>accept()</em> with the server app, and then process an FD_CONNECT message. Are we ready? Then let’s first call the <em class='bbc'>connect()</em> function. Where you ask? Well, where you normally would. Let’s not get this mixed up – the FD_CONNECT event happens <em class='bbc'>after</em> the connection has been established, so you don’t call connect from the FD_CONNECT event handler, we’ll get there soon. Just call <em class='bbc'>connect()</em> as you normally would, after you set all the IP addresses and port numbers and so on.<br />
<br />
 [indent]<pre class='prettyprint'>connect(Port, (LPSOCKADDR)&Server, sizeof(Server));</pre>[/indent] 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.<br />
<br />
 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 <em class='bbc'>accept()</em>.<br />
<br />
 [indent]<pre class='prettyprint'>...<br />case FD_ACCEPT:<br />  {<br />	// holds size of client struct<br />	int lenclient = sizeof(client_sock);<br /><br />	// connect to the server<br />	Port = accept(wParam, &client_sock, &lenclient);<br />  } break;<br />...</pre>[/indent] 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 <em class='bbc'>have</em> to call <em class='bbc'>accept()</em>, 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.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Re-enabling Functions</strong></span><br />
<br />
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.<br />
<br />
 For example, the re-enabling function for FD_ACCEPT is <em class='bbc'>accept()</em>. When an FD_ACCEPT event is posted, no other message will be posted until the application handles the current one and then calls <em class='bbc'>accept()</em>. Once <em class='bbc'>accept()</em> 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.<br />
<br />
 The point is that without calling <em class='bbc'>accept()</em> 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 <em class='bbc'>recv()</em> and <em class='bbc'>send()</em>. Gee. What a surprise.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Sending and Receiving Data</strong></span><br />
<br />
I wanted to split this into two parts, but I decided just to explain FD_READ first and save the more complicated FD_WRITE for last. That said, the FD_READ event is easy enough to handle. WinSock will notify you when the network buffer has more data for you to collect. For every FD_READ event you will call <em class='bbc'>recv()</em> just like so:<br />
<br />
 [indent]<pre class='prettyprint'>int bytes_recv = recv(wParam, &data, sizeof(data), 0);</pre>[/indent] Nothing terribly different, except you can’t forget to stick in that wParam. Also, a word of warning: You are not guaranteed that you will receive the entire buffer in one shot. This means your data may not come through all at once. Be sure to implement a test using the bytes received (which happens to be the return value of the <em class='bbc'>recv()</em> function) to determine if you have all of your data before manipulating it.<br />
<br />
 Now the FD_WRITE event is a bit more complicated. Mainly because of the way it is called. First of all, an FD_WRITE event is always generated when you first establish a connection with another socket. So you think all you have to do is plunk in a <em class='bbc'>send()</em> function with whatever else you’ll need and you’ll be fine. Oh if that were only true. Listen carefully: the FD_WRITE event is triggered only when there is more room in the buffer with which to write data. Huh? Allow me to explain.<br />
<br />
 First off, the <em class='bbc'>buffer</em>, as I use it here, is the network buffer, which you write information to. That information is then sent over the network (intranet or internet) to the receiving socket. So you’d think that since there will always be space left to write data if you don’t fill it up all at once, that FD_WRITE events will just keep coming and coming right? Wrong! Read the rules again. It says when there is <em class='bbc'>more</em> room. Not <em class='bbc'>enough</em> room, <em class='bbc'>more</em> room. This means you have to fill it up first! How do you do that?<br />
<br />
 The general idea is to create an infinite while loop in which you will continuously send data until you max out the buffer. When is happens, <em class='bbc'>send()</em> will return the error WSAWOULDBLOCK. This means that if it were a blocking socket, it would wait (stop execution) for more room in the buffer and then send. But since it isn’t, you get the error. So now that you’ve filled up the buffer, you just have to wait until <em class='bbc'>more</em> room becomes available so you can write again. And bingo! Up pops another FD_WRITE event. Do you have any idea how much trouble I had to go through to figure this out? You people are so darned lucky! Here’s an example of an FD_WRITE event handler:<br />
<br />
 [indent]<pre class='prettyprint'>case FD_WRITE:  // we can send data<br />  {<br />	// enter an infinite loop<br />	while(TRUE)<br />	{<br />  	// read in more data from the file and store it in packet.data.<br />  	in.read((char*)&packet.data, MAX_PACKET_SIZE);<br /><br />  	// increment the amount of data sent<br />  	data_sent += strlen(packet.data);<br /><br />  	// send the packet off to the Server if it is filled<br />  	if (send(wparam, (char*)(&packet), sizeof(PACKET), 0) == SOCKET_ERROR)<br />  	{<br />    	// check if the network buffer is full and can send no more<br />    	// data. If so then break from the loop<br />    	if (WSAGetLastError() == WSAEWOULDBLOCK)<br />    	{<br />      	// break from the loop – buffer is full<br />      	break;<br />    	}<br />    	else // another error<br />    	{<br />      	// display an error message and clean up<br />      	CleanUp();<br />      	return(0);<br />    	}<br />  	}<br />	}<br />  } break;</pre>[/indent] There, you see? The implementation isn’t so hard after all! It was only the concept that was messing with your head. If you use this technique, the loop will end when the network buffer becomes full. Then, when more space is available – another FD_WRITE event will be triggered, and you can send more data.<br />
<br />
 Before you jump to make use of your newfound knowledge, allow me to clarify the use of the FD_WRITE event. Do not expect to be using this event at all if you are not going to be sending large pieces of data at once. The reason for this is simple – if you base all you information transactions on FD_WRITE and never send enough to fill up the buffer, after that first trial FD_WRITE event generated at the beginning of the connection – no other FD_WRITE event will be triggered! Therefore for games, where you send as little data as possible, just forget about setting a socket for the FD_WRITE event and use <em class='bbc'>send()</em> wherever you need it. FD_WRITE is best used for transferring files, in my experience.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Conclusion</strong></span><br />
<br />
Well, so far this is the longest article I’ve written. I’ve tried to keep it as short as possible to hold your attention but there was just so much information to cover. Asynchronous sockets can be really confusing at first if they are not explained correctly, and I hope I did a good job of teaching you how to use them properly. If you have any questions or comments, please <a href='mailto:drew@gamedev.net' title='E-mail Link' class='bbc_email'>email me</a>. I will try to answer as many as I can. Also, by emailing me, I’ll have your address in case I have any new information or corrections to give out. Hope you enjoyed reading the article as much as I enjoyed writing it. I’m looking forward to my next one. Until then…<br />
<br />
<span style='font-size: 12px;'><strong class='bbc'>Note on the Source</strong></span><br />
<br />
The source code attached to this article demonstrates an asynchronous application. Source is free for any use you wish, credit would be nice!]]></description>
		<pubDate>Thu, 01 Feb 2001 00:19:19 +0000</pubDate>
		<guid isPermaLink="false">9d99197e2ebf03fc388d09f1e94af89b</guid>
	</item>
	<item>
		<title>Networking for Games 101</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/networking-for-games-101-r1138</link>
		<description><![CDATA[<span style='font-size: 18px;'><strong class='bbc'>A brief history of the Internet</strong></span><br />
<br />
Before we begin this journey into the inner workings of networking in games, it's important to define some terms, and get some background on the Internet and how it works. This is of inestimable help later when trying to explain why certain things are done the way they are when coding for the net, plus, if you're anything like me, it's just plain interesting.<br />
<br />
 I'm going to go over some history of the Internet, with some simple examples of how it works, without getting too technical. This is not intended to be a programming reference document, more an enlightenment of what others are talking about when they talk about latency, pings, TCP/IP and so on. I will avoid those areas of the net that aren't directly related to games, since there is no reason to bore the pants off anyone more than is strictly necessary. This is not a 'how to' document, but more a FYI type of thing. There is nothing in this about making your home system better over the Internet, but more an explanation of why so many Internet games have networking troubles, and where they come from.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>So let's begin</strong></span><br />
<br />
The Internet as everyone knows it came about from a much smaller network called ARPANET that the Pentagon created a) because America was on a science kick in the 60's and wanted to get a head start in burgeoning industries and b) because the Pentagon wanted to use and keep tabs on the expensive mainframes it was funding at places like MIT and UCLA without having to use multiple remote terminals.<br />
<br />
 To cut a long story short, the pentagon put out a contract to tender that would link multiple mainframes together, for use in real time. This would mean that one man at one terminal should be able to access multiple machines, share data and run programs on different machines.<br />
<br />
 From this contract, the concept of packet switching and routers was born. Now everyone bandies those words 'routers' and 'packet switching' around, but what do they actually mean? Well, first up, lets dissolve one common misconception. Many people use the phone system as an example when discussing the Internet. "It's like phone system" they say "You have an IP address that's like a telephone number". Well, not really. A better one would be to use the post office as an example. Imagine that when you send a file from one computer to another it's like a letter being sent. It first goes to your post office, where it is examined, and it's decided if it's intended for someone that has an address that post office serves. If it's not, then it's forwarded to another post office for examination again. Eventually it will arrive at a post office that says, "Oh, I know where the post office that this letter is intended for is located" and it's forwarded directly to the correct one, which then sends it on to the intended recipient. Long winded but you get the idea. Well, a router is effectively a post office. It sorts files that come in and decides what to do with them and where to send them. This is very different from the phone system where you end up with a direct link between you and who you are calling. With routers, there is no direct link. Incidentally, there is a common myth that states that the original APRANET and by default, the Internet, was designed to withstand a nuclear war, so that if one machine was taken out, then others would still be able to communicate, since there was no one route that everyone depended on. Having researched this, there is no actual proof that this was ever an original requirement. It would be able to withstand loosing a large portion of it's connecting machines, but that would appear to be more of a side benefit than an original requirement.<br />
<br />
 Anyway, back to packet switching. When you send a file over the Internet, you don't actually send the whole thing in one big chunk. It's broken up into small packets - like postcards if you want to continue the post office simile - and each one is transmitted one after the other. The beauty of this is that the routers can handle many, many of these little packets, without ever having to know what's in them (or indeed, the order they are transmitted in). So your packets get mixed in with someone else's, and the data stream gets maximum efficiency. All your machine has to do is create the little packets, number them, so they get re-assembled on the other end in the correct order, and send them out to the router. Of course they need an address too. That's where IP's come in. An IP is a unique address for your machine on the Internet. It's a 4-digit number, all of which are between 0 and 255. For instance 204.57.198.32. All those www.whatever.com are actually converted into IP addresses when packets are exchanged with another machine on the net. Sometimes these are specific and constant on one machine, more often than not they are dynamically allocated by the host system. Every time you log onto you service provider, they send you an IP address they have free from a range that's been allocated to them. For instance your ISP may have the range 204.198.32. 0 to 255, which gives them 256 possible IP addresses. 256 people can all be using the system at once, but no more than that. When you log in, the system looks to see what IP's are free, and sends you one. That way more than 256 people can be on the books for this Host, but only 256 can use it at once.<br />
<br />
 The alternative to this would be the phone system approach, which would mean creating dedicated routers that would reserve an entire line for you to send data to and from the other computer, but that would not get used most of the time, especially if you are doing stuff like typing in real time. You may think you are a fast typist, but in the time between a message going to and from your machine to another, the network could have transmitted War and Peace several times. A good simile that I heard used would be "like reserving the entire Interstate road system to drive a car from Washington DC to LA". You would never dream of doing that, instead you share it with other car drivers. Just like on the Internet. Maybe that dumb 'super highway' label thing has some merit after all<br />
<br />
 I'm sure you can see how the sharing lines with others, and breaking messages into small packets is the most efficient use of network time and data streams. The same system is in use today as was originally designed for the ARPANET way back when. Why? Cos it works real well<br />
<br />
 Where do ISPs come into this? Let's think of it this way. The routers are machines that sit attached to mainframes and stuff that we are treating as big post offices. An ISP (Internet Service Provider) is one step removed from that - like the postman himself. They are attached to a machine that often has a router (not always), but they also have a ton of modems attached to them. Your little PC at home uses its modem to call up the modem attached to the ISP's machine, which then accepts your packets and then forwards them, in bulk and mixed in with everyone else's, to the Internet with a capital I.<br />
<br />
 Cable modems, ISDN and DSL are pretty much the same thing, except that the modem-to-modem part is removed, and faster bandwidth communication devices are used instead. In fact DSL is basically just a faster modem with a better phone line anyway<br />
<br />
 Ok - so now we know how data gets to and from, and about on the Internet. It all sounds cool and froody, so what's the problem? Why doesn't Quake play well then? Well, there are many potential problems. I'll list some - and by all means not all - here.<br />
 <ul class='bbc'><li><strong class='bbc'>The routers.</strong> Routers have a finite capacity. They can only examine and forward one packet at a time. The rest sit in a 'queue' waiting to be dealt with. Once the queue is full, any packet that gets submitted will be ignored. Welcome to the world of dropped packets. Actually, this is pretty rare, you have to have a real heavy load on a router before it does this, but it does happen. Another problem with queuing is that it takes time. It delays your packet before it's processed and adds to the round trip time it takes for your packet to get to its destination. More often there are problems with the router itself, or it leads to a dead end. To explain, when a packet hits a router, it's destination address (its destination IP) is examined, and the router compares it against it's own route tables. These routes come in two flavors, static and dynamic, (at least they do now - older routers have only the static lists). Route Tables are basically a list of destination addresses it knows about. For instance router A gets a packet that wants to go to Router F. Router A can see routers B and C - but not router F. What does it do? It requests those routers that B and C can see (and in this case both know where router F is), and decides based on the info it receives which one to send it to. This info includes loads on the B & C routers, number of hops to get to Router F and so on. Since loads can vary second to second, the decision to send it via B or C can change second to second. Hence you can see how multiple paths can be used for packets going to the same destination. So what's the difference between static and dynamic trace routes? Static are routes that are 'programmed in' to the router. It KNOWS these routes exist, and expects them to be there at all times. Dynamic routes are those that it gets from other routers. This list is constantly changing and updating dependent on what routers are up, what routes are the fastest and what routers may be inoperable further up the chain. If a line goes down somewhere, or a router breaks down, most routers with only static lists don't know/care. They send it on, since they KNOW the route is supposed to be there, but once it gets to the next one, there is nowhere for it to go, because a line was down. Before dynamic trace routes were around, if a line went down between you and your destination, you could well be SOL. Obviously I've take some liberties with exactly how routers work and simplified it considerably, but this is more a layman's document than a programmers guide.<br /><br /> One of the worst things about all this is that there is nothing that you, as the user, can do about this. The Internet was designed to be robust, in real time, but not instant. It's a shame, but Quake wasn't on their minds at design time.<br /><br /> As an aside, you might be interested to know that with the new IP design that has 6 IP numbers instead of 4 (apparently we are going to run out of IP addresses by 2014), some new addressing schemes include a 'preferred route' in the header for IP packets. This way the router itself won't be doing the decision-making, but letting the packet creator chose the route itself. At least this will gain consistency, and reduce lost packets & out of order packets, but at the risk of speed of transmission.</li><li><strong class='bbc'>TCP/IP - UDP.</strong> As we learnt in the last bullet point, you can't guarantee that packets are going to be delivered at all. Another draw back to this situation is packet ordering. You may transmit you packets in order, but they may end up going via different paths, and encounter different delays in getting to their destination, with the practical upshot that they get there out of order. This is a problem, and there is not much that the hardware of the Internet can do about this. But a solution is in hand in the shape of Internet Protocols. We've all heard about TCP/IP but what does it mean? Well, it stands for Transmission Control Protocol / Internet Protocols. While we are talking about initials lets define UDP as well. That's User Datagram Protocol. So we know that they stand for. Does this make everything clear? No. Ahhh. So let's clarify. TCP/IP and UDP/IP are two layers of systems. The IP bit is the part that figures out the transmission of packets of data to and from the Internet. UDP or TCP hands it a big fat old packet of data, and the IP part splits it up into sub packets, puts an envelope around it, and figures out the IP address of its destination, and how it should get to where it's going, then sends it out to your ISP or however you are connected to the Net. It's effectively the bit where you write down what you want to send on a postcard, stamp it, write the address on it, and stuff it in a mail box.<br /><br /> UDP and TCP are higher layers that accept the packet of data from you, the coder or you, the game and decide what to do with it. The difference between UDP and TCP is that TCP guarantees delivery of the packets, in order, and UDP doesn't. UDP is effectively an access way to talk directly to IP, whereas TCP is an interface between you and IP. Complicated, but you should get the drift. It's like having a secretary between you and your mail. With UDP you would type up your letters yourself, put them in an envelope etc. With TCP you would just dictate the letter, give it to her and let her do all the work and follow up to be sure the letter arrived.<br /><br /> You can see TCP/IP in action right this second if you want. If you're in windows, open up an MS-DOS prompt and type PING 205.229.73.43 and press return. What you've just done is sent a message to the machine that runs this website and said "are you there?" And it's replied, "Yes, I am." The values you see there is the time taken for the packets of info to make the round trip - from you to them and back again. This is called Ping time, or Latency. Latency is one of those weird phrases that mean different things to different people. We here at Raven treat it as an average. Ping is the round trip for one packet; latency is the average round trips over the last 30 or so packets. As a rule of thumb, those hosts that you are trying to get to that have the least amount of routers to go through are the ones that will have the lowest ping. Usually these are the closest to you in physical location, but not always. If you want to see the route you have to go through to get to a particular host, type tracert 205.229.73.43 at the MS-DOS prompt. This returns all the routers your packet hit on the way to the host.<br /><br /> However, all this wonderful work-done-for-you comes at a cost. In order to be sure that packets that are sent via the Internet get there ok, TCP expects an Acknowledgement (an ACK in net parlance) to be sent back from the destination for every packet it sends. If it doesn't get an ACK within a certain time, then it holds up sending any new packets, re-sends the one that was lost, and will continue to do so until the destination responds. We've all seen this in action when you've gone to a web page, and half way through the download it stops for bit and then restarts. Chances are (assuming its not an ISP problem) a packet has been lost somewhere, and TCP is demanding it gets resent before any more come down the pipe.<br /><br /> The problem with all this is the delay between the sender realizing something is amiss, and the packet actually getting through. This can get into the seconds sometime, which is not that much of a worry if you are just downloading a file or a web page, but if it's a game packet, of which there are at least 10 a second, then your in real trouble, especially since it's holding up everything else. This is actually such a problem that almost no games use TCP/IP as their main Internet protocol of choice, unless it's it not a real time action games. Most games use UDP - they can't guarantee order or delivery, but it sure is fast. We'll talk about how they handle this later.</li><li><strong class='bbc'>ISPs.</strong> Often the bane of a game players life. Some ISP's get all upset about the idea of people playing games using their precious bandwidth that they actually use Packet Sniffers. These are programs that scan the packets going through the network looking for Quake game packets, and when they find them, they kill them dead. What a bunch of spoilsports. I'd be interested to know exactly how they know these packets are Quake packets, since packets can contain anything, but apparently there are programs like this out there. Of course the other big bit of bad news about ISP's is their server load. The way that modem banks work is that all the modems tie into one large pipe that goes into the main host machine that then forwards these packets to the Net itself. Now, the lower the spec machine that is used for the hosting, and the larger the bank of modems attached to it, the longer the response time is on both packets going in and out of the machine. Fairly obviously the main pipe is only so wide, with the upshot that once it's full, your modem waits. Of course this doesn't just apply to the ISP machine, this can apply to any of the routers on the way and also the destination machine too - we've all seen those download problems on machines that have something popular on them. This means that you may be connected to a 56k modem, but you're only getting 28.8 performance out of it, due to limitations beyond your control. And this sucks. Some ISP's are worse than others, with cheap crap modems that drop the connection and stuff like that. I won't mention AOL here. Again, all you can do is just shop around.</li><li><strong class='bbc'>Network coding in the game.</strong> This is pretty much all we as developers can do to accommodate the intricacies of the Internet, but there is a surprising amount that can be done. Reading all of the other points kind of makes you wonder how online real time gaming can ever be done at all, but it has to be said, the net works more than it doesn't. We'll discuss some of the cool things that can be done programming wise in a second, but first, we'll look at some of the no-no's. First up is the use of TCP/IP as your main protocol. I've already explained why this can be (and usually is) bad news. It is often used during game setup to ensure all players have the correct starting data, before we start the game data flowing.<br /><br /> Secondly, packet bloating. You have to be careful only to transmit that data that is required; otherwise you are just sending data for the sake of it. The larger the packet you give to the UDP system, the more you are asking the network to handle. This has a big impact in client/server setups when your packet gets to the server, since YOU are only transmitting one packet, but the SERVER is receiving many such packets. This also impacts modem bandwidth. If you are running a 28.8 and getting a pretty good sustained throughput, you need to be sure that you are not allowing the packets to exceed what it's possible to push through the modem. Too big = packets getting shunted into a buffer while the modem struggles with what it's got to send, and eventually the buffer overflows and you end up at a crawl, assuming the game hasn't already puked.<br /><br /> Third, packet frequency. Are you expecting packets to be sent faster than the communications infrastructure can really handle? You may be running at 60 frames per second, but you can bet that the Internet will have trouble sustaining that kind of packet rate.<br /><br /> Fourth is handling out of order packets (assuming you are using UDP) and dropped packets entirely. This is more involved and requires you to be cleverer than you might think. However, if you don't handle it right, you end up with missing events, missing entities, missing effects, and sometimes, completely FUBAR'd games.<br /><br /> Lastly, there is the aspect of online client cheating to consider. With CPL and other frag fests offering cash to winners, this is more important to consider than it used to be.</li></ul> So ok, we've seen the mess that is the Internet, and all the pitfalls, what can we do about them as game developers?<br />
<br />
 Rats, I knew someone was going to ask that. I thought I was done, check please. But noooo, more stuff to have to type up. Oh well.<br />
<br />
 Well, the first thing we should do is define the difference between client/server type games and peer to peer games.<br />
<br />
 Peer to peer involves two or more games talking to each other, each running the game itself and only exchanging input data. This reduces network traffic to a minimum, but brings several other problems to the table, like coping with lost traffic. This is far more important when more than one game is running, since contention occurs over who is correct and who is not. Variance in game play can get very sticky in these situations, as each game must stay synchronized with the others. Additionally, each game must wait for the input from the others before it can simulate the next frame – remember playing DOOM and it would lock up momentarily?<br />
<br />
 Client/Server involves one machine running the game and dictating to all the clients what the state of play is and what they should be displaying. Effectively the clients become pretty much dumb terminals transmitting the user input to the server, and letting it handle almost everything. They draw the scene the server tells them to display, and play the sounds the server tells them to play. Actually, it's not quite as bad as this, as the server does on occasion tend to offload functionality onto the client, but that's the basic idea.<br />
<br />
 What I'm going to discuss has more to do with Client/Server type setups than peer to peer since almost all online type games have some degree of Client/Server architecture to them - every game has to have one client that 'hosts' the game and is considered 'correct' in the case of world event contention between peers. (Unless they don't, in which case, you'd just get an "out of synch" error and quit.)<br />
<br />
 Ok, now on to our problem list - the TCP/IP selection is a no brainer - we don't have to discuss that anymore.<br />
<br />
 One down.<br />
<br />
 Packet bloating. This one can be tricky. Obviously a max packet size in the code is in order here to stop modem buffer overloading. We here at Raven are actually implementing a floating max packet size, for those people who are running over a local network, or that have large bandwidth available to them. When you hit a packet that breaks your buffer size, the secret is to split the data into two smaller chunks - only send in the first packet what is really necessary to be there that instant. Data like entity movements and so on. Stuff like chat messages can wait till the next packet, since no one is going to miss that being one packet late. Still, tough decisions need to be made as to what's important and what isn't, and sometimes this can make the game feel a little sluggish and un-responsive. This is where the floating packet size can be helpful, since it should remove that feeling from those with large bandwidth or running local games. Not the best solution, but one that's worth a try.<br />
<br />
 Other stuff that's worth thinking about includes tokenizing text messages. If your server is sending a lot of preset text messages, it makes more sense to have these pre-loaded on the client, and just send them a text string reference number rather than the whole string. This reduces out message traffic considerably. The same trick can be played with sending down filenames when the server asks the client to load something. For instance you can break down the file into path names, and then filenames. If you are asking for a bunch of sound files to be loaded, then only send the path once, and from then on, refer to the path as a token in the string. For instance we'll ask the client to load "sound/weapons/death.wav". Once the client receives this string, it will store away the path as a token, and the next time we want a sound, we send "%1pain.wav" and the client knows by the %1 to go away and use that path it got first time to load this sound. Little things, but they all help.<br />
<br />
 Something else worth considering is reducing the complexity of floating point data. Traditional floating point is 32 bits long - 4 bytes. The question is, do you really need that degree of accuracy? Reducing 32 bits to 16 of floating point is not out of the question; many games do this, but I'll bet you haven't noticed. While we are on that subject, being very sure of the size of the data you need to transmit is also a necessity here. If you are sending a value of between 0 and 170, do you really need a long word to do it? It would fit in a byte, and you've just saved 3 bytes. Obvious when you think about it, but you'd be surprised at how much it gets forgotten about when you are just getting the game working.<br />
<br />
 Only sending objects that have relevance to the scene you are displaying is helpful. Remember, the client is dumb, and doesn't need to know about what's out of the view or hearing threshold. Who cares? They aren't being rendered or heard, so what difference does it make? The server knows about them, and it's running the game, not you. This sucks of course if you are out in the open, or in a space sim, since everything is visible, but that's a game design decision that you make based on your technical abilities.<br />
<br />
 Further to that, offload special effects. Remember the client is pretty dumb, but it's smart enough to do clever effects for you. There is no reason for the server to be sending all the info on effects to the client, wasting both server time and network space. It's enough that the server says "an explosion happens here" and the client does the rest, superimposing that effect on the main display. We did this in Heretic II, which was the major reason it ran so well on the lower end machines.<br />
<br />
 Of course the biggest thing you can do to help packet size is to delta-compress info. Without giving away all of our (game developers' that is, not just Raven) technical secrets, the idea here is to only transmit data that has changed from one frame to the next. Simply keep a copy of what you sent last time, and on an object-by-object basis, compare what you want to send this frame with what you sent last, and only transmit that which has changed. Of course this doesn't work when you have a new object to transmit, since it all has to go across. But then if you figure out the percentage amount of this happening, it comes out to about between 5% and 10% of the time. That's some saving.<br />
<br />
 If you want to, you can implement some compression schemes on the resulting packet to make it even smaller, but in these cases the trade off of time to compress on the server and decompress on the client can be worse than having a slightly large packet.<br />
<br />
 Frequency - control over this is a must. Quake actually has a server that runs at 10 frames per second, transmitting data over the net at that rate. Actually, it does transmit faster than that when it's doing stuff like downloading client requested files, or responding to server info requests, but during game time, the client expects data at a 10fps rate. It runs at 10fps a) because of the amount of data it is processing for each client. And b) because this is a nice easy network packet rate to sustain.<br />
<br />
 There, that one was easy.<br />
<br />
 Out of order and missing packets. The trick here is to only treat one symptom and ignore the other. If you number your game packets (when we talk about packets here, I mean game server frame packets - IE the packet that contains a complete frame update from the server) as they go out to the client, the client can know if it gets an out of order packet. The simplest solution is to dump it, and treat it as a missed packet entirely. Doing this is a must if you are dealing with deltaed packets, since the delta values in the packet refer to the frame that came before.<br />
<br />
 If you keep a copy of the last packet you received from the server on the client, you can compare the latest one you got to it and see if an object has been dropped. At that point, you can either just dump the object immediately, or store it off into a list and check a few packets down to be sure it's still gone, and then dump it. The beauty here is that you never actually have to send a 'remove' function to the client from the server, since by omission from the game packet from the server, the object is gone. Even if you have some dropped packets, it doesn't matter since eventually you will get one and that object will still be missing in the latest packet, and thus it will get deleted. Cool eh?<br />
<br />
 Now we'll take a moment and talk about client prediction. And what a clever but nasty beast this is. In the cases where both the client misses a packet from the server, and the time between getting normal gaming packets, (think about it - the server may only be running at 10fps, but that doesn't mean you want the client side representation to), the client needs to be doing something to make it look like it IS still getting data. So we predict the world and events in it. Since we know what's going on with the client's player - after all, we are right there at the input point right? - we can predict what he is going to do. If he fires a weapon, we can show it on screen, since that's what we know he's going to do. We can also predict - to a lesser degree - what the other players are doing, at least to complete out any animations they may be in, if they are dropping still have gravity performed on them and so on. Now of course this only works for a time measured in seconds, but usually that's enough for the packet system to come back on line, and start re-receiving stuff from the server, at which time the client can correct it self for any events that it predicted wrong. At the best, it's totally on target, and you will never have known that you were missing data. At middle, the client is a bit out, so it starts correcting via a smoothing operation, that way no one 'snaps' really obviously to a new location. And at worst, you are dead via an attack you didn't even see, since it occurred while you were missing packets. However, there is no way around this situation so it's something that has to be lived with, and it's better than jerky motion and snapping updates.<br />
<br />
 However, what do you do if you miss a baseline packet? IE one that has a new object in it that wasn't there before? You've missed all the information that came down initially, but you will be getting updates from that point on. Well, to be honest - that's the trick isn't it? I've given away most of the tricks of the trade already, but some must remain. I'll give you a clue though; it is possible to fix a situation like this.<br />
<br />
 In every type of game there are some packet types that WILL require a guaranteed delivery. So be prepared to create some kind of structure to cope with this, because UDP doesn't. But be sure you don't use it too much or you will end up back with the same problems that TCP/IP has.<br />
<br />
 Online Cheating. There are a few ways to try to deal with this, but be warned, what's man-made is man-hackable. This is not so much a big deal at big frag fests since all the matches there are moderated, but it can have an impact on those that qualify for these fests. And of course, it just plain sucks to be playing on a server where someone is unbeatable because they are cheating. Cheating can occur in many ways, modifying the client to never display walls in the game, adding lights or white skins to other players, displaying a local map (if you want to get really ambitious), modifying your aim so it's always dead on other players, or simply firing a weapon at an opponent with deadly aim the moment they are in sight. All of these are hacks to the client end of the game, and when done properly, are pretty un-observable back at the server. There is some stuff you can do, checking the accuracy of each player and dumping those that go over a certain scale. You may loose some really good players that way, but it's unlikely that anyone can get over an 80% hit rate all the time. All the checks of the client in the world can really be gotten around since the result of the check has to be returned to the server at some point, and if it's intercepted there and replaced with what the server expects, the server is fooled. Using the result to decrypt the data that comes from the server is possible, but again, it's done on the client side and with enough patience and a good dis-assembler it can be gotten around. Client integrity is the key here, and keeping it the aim. The Quake 1 & 3 solution, that of a virtual machine, where instead of the client loading the game up the client 'builds' or 'compiles' the game it's going to run via instructions from the server, is a good start, since re-writing someone else's compiler is beyond all but the very best of hackers. God knows, writing it in the first place is a nightmare I wouldn't want to contemplate. But it is within the bounds of possibility. All the games developer can do is make it as difficult as he possibly can for the budding hacker and be content with that.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Last thoughts for Developers</strong></span><br />
<br />
Peter Lincroft who was involved with X Wings vs. TIE fighter had an article in Game Developer Magazine and did a talk at GDC last year about his experiences with net gaming, and I'd like to reiterate some of his ideas here for completeness' sake.<br />
<br />
 When testing a game, make sure you find a really horrible ISP to do some real Internet testing. Most games get built and tested to start with on the internal LAN at the developer's offices. This isn't really a fair test, since LANs rarely drop packets and have great PINGs. Find a bad ISP and do some REAL testing. This really works wonders for you later.<br />
<br />
 Emulate Internet conditions. Stick some code into your code base that emulates packet dropping. Have it settable so you know at what point your game is going to break down - is it 10% drop out or 30%? These are things you should know so you can automatically drop someone from a game if this occurs. Something to bear in mind here is that the Internet doesn't typically just drop one packet. Usually they occur in batches, so don't just dump one at a time, do them several at a time.<br />
<br />
 Remember your server is going to be sending out far more data than each client has to worry about. If client messages are around the 2k mark a second, and there are 10 clients, then the server is banging out 10x2k packets, which is 20k. Be sure that the communications infrastructure you are using is capable of supporting this.<br />
<br />
 Well there you have it, some ramblings and thoughts on Networking 101 for Games. I've probably made some mistakes, but the gist of it should be sound. Have fun out there, and be amazed it works at all<br />
<br />
 Big thanks must go to James Monroe for adding any inaccuracies this document may have. Blame him and send him mail for any mistakes instead of me.]]></description>
		<pubDate>Wed, 26 Jul 2000 11:02:41 +0000</pubDate>
		<guid isPermaLink="false">7e19999864bb17b5cf10e68e3c7e6276</guid>
	</item>
	<item>
		<title>WinSock2 for Games</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/winsock2-for-games-r1059</link>
		<description><![CDATA[<span style='font-size: 18px;'><strong class='bbc'>Introduction</strong></span><br />
<br />
I went on #gamedev (my nick is jadam) the other day and asked if anybody knew DirectPlay.  I was expecting someone to just say "Yeah, go to <a href='http://www.directplay.com/' class='bbc_url' title='External link' rel='nofollow external'>www.directplay.com</a> and get an online book!"  Not a single person there knew it!  I asked what they used for networking and everyone said WinSock.  I was originally going to learn DirectPlay, but I guess there aren't enough resources at the moment.<br />
<br />
 I had used WinSock before, but that was in Visual BASIC.  Back then; I was amazed at how simple it was.  Well I thought that WinSock in C++ would be just as easy;<em class='bbc'> big mistake...</em><br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>What is WinSock?</strong></span><br />
<br />
WinSock is an API that will let you create and use <em class='bbc'>sockets</em>.  Sockets are connections, usually through the Internet or a LAN.  These connections are two-way, meaning that both sides can send and receive information.  Each computer that is in the Internet or on a LAN has an <em class='bbc'>IP address</em>.  An IP address consists of four bytes separated with periods (".").  An example of an IP address is "129.240.3.5".  Notice that each of the four numbers that makes up an IP address is a byte, so it can range from 0 to 255.  256^4 = 4,294,967,296 that makes over 4 billion different addresses, which is enough for now <span style='font-family: Wingdings'>J</span>. So a socket can be created from the computer at address 37.143.125.23 to a computer at address 64.253.241.72.  The problem is that if the computer wants to have more than one socket at a time, we will need a further address to identify our socket.  This further address is called a <em class='bbc'>port</em>.  We use ports all the time when we are in the Internet.  For example, the standard port for HTTP (web surfing) is port 80.  That means that if we type <a href='http://www.intertainment.8m.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.intertainment.8m.com</a> into our browser, the browser will find out what IP address that server is and try connecting to port 80.  Ports 1 - 1000 are pretty much reserved for standard <em class='bbc'>protocols</em>.  Protocols are "languages" used to communicate with each other.  For example HTTP is used for web page transfer, FTP is used for file transfer, and NNTP is used for newsgroups.  Anyway, WinSock gives you all the power to create sockets, connect, disconnect, close, <em class='bbc'>listen</em> to a port.  Listening is when a program just sits at a specific port and waits for some computer to connect.  Programs that listen to ports are called <em class='bbc'>daemons</em>.  For example a HTTP daemon will just listen at port 80 and then give you index.html or whatever site on connection.  I think that was enough theory to learn some more theory.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>TCP or UDP</strong></span><br />
<br />
What is the difference between TCP and UDP?  Well, first of all, TCP and UDP are both protocols used to transport data.  TCP uses the <em class='bbc'>stream</em> architecture while UDP uses the <em class='bbc'>data gram</em> architecture.  Stream means that if we have a socket that is connected, data will be sent reliably.  The data gram architecture is unreliable and data may be split up, lost, or even duplicated.   Because of UDP's disadvantages, we will use TCP.  There are still other protocols that can be used with WinSock 2, such as DecNet and a bunch of others.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Architecture</strong></span><br />
<br />
A very important thing to think about is what architecture to use when making a multiplayer game.  The two (main) architectures are <em class='bbc'>client - client</em> and <em class='bbc'>client - server</em>.<br />
<br />
 <span style='font-size: 12px;'><strong class='bbc'>Client - Client</strong></span><br />
<br />
The client-to-client (also called <em class='bbc'>peer-to-peer</em>) architecture is quite simple, yet should only be used in 2 player games.  Two clients (player's computers) connect to each other using their opponent's IP address or domain/host name.  One problem with this sort of connection is that exchanging IP addresses before you play gets on your nerves quickly.  To play against someone, you will have to know his or her IP address.  Some people trade IP addresses via email or chat (IRC, ICQ, AIM, etc).  Another option is to a server that is especially set up to do nothing but help players swap IP addresses.  This means that games are private and two-player.  This may or may not be a good thing.  The two machines will just exchange game states with each other and both will do full processing (wasting resources).<br />
<br />
 This is a diagram of the client - client architecture:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[7eac483d938f488b88c45a172cbac835]' id='ipb-attach-url-3045-0-03768800-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3045" title="Image30.gif - Size: 2.01K, Downloads: 58"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-70154700-1307728900_thumb.gif" id='ipb-attach-img-3045-0-03768800-1330207729' style='width:250;height:62' class='attach' width="250" height="62" alt="Attached Image: Image30.gif" /></a> </p><br />
 Or in terms of more than two machines:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[7eac483d938f488b88c45a172cbac835]' id='ipb-attach-url-3046-0-03789400-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3046" title="Image31.gif - Size: 4.31K, Downloads: 66"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-61343400-1307728919_thumb.gif" id='ipb-attach-img-3046-0-03789400-1330207729' style='width:250;height:151' class='attach' width="250" height="151" alt="Attached Image: Image31.gif" /></a></p><br />
 <span style='font-size: 12px;'><strong class='bbc'>Client - Server</strong></span><br />
<br />
This is the way to go.  A fast computer with a fast internet/LAN connection starts a special server application.  Everything goes through the server and the server may do processing for all the clients (which cuts down on processing if the game is only one screen big).  The server may or may not process data, depending on the way the game was programmed.  The cool thing about servers is that there can be (theoretically) unlimited players and the server can do the processing while all the clients just display what the server sent them.  Another cool thing about servers is that they aren't usually started on some private computer, but on multiplayer servers, which have a domain name (<a href='http://www.mplayer.com/' class='bbc_url' title='External link' rel='nofollow external'>www.mplayer.com</a>, <a href='http://www.heat.net/' class='bbc_url' title='External link' rel='nofollow external'>www.heat.net</a>, etc.) so you donÆt have to type in the IP address, or exchange it.  Also, client - server games will often have a <em class='bbc'>lobby</em>, where you can find other players, wait, or chat.<br />
<br />
 Here is a diagram of the client - server architecture:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[7eac483d938f488b88c45a172cbac835]' id='ipb-attach-url-3047-0-03809500-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3047" title="Image32.gif - Size: 2.62K, Downloads: 69"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-75699800-1307728949_thumb.gif" id='ipb-attach-img-3047-0-03809500-1330207729' style='width:250;height:97' class='attach' width="250" height="97" alt="Attached Image: Image32.gif" /></a></p><br />
 There are three sockets in the diagram.  There is the client socket, which obviously is the socket belonging to the client computer.  The server uses two sockets.  In the beginning there is only one socket, the listen socket.  The listen socket listens at a well-known port (a port that the client knows).  When the listen socket accepts the connection, it creates a new "connection socket".  This may seem strange, but it is perfectly logical because if the client used the listen socket to communicate and exchange data with the server, then no one else could connect during that time.<br />
<br />
 Here is a diagram of multiple computers playing a client - server game:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[7eac483d938f488b88c45a172cbac835]' id='ipb-attach-url-3048-0-03828100-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=3048" title="Image33.gif - Size: 4.02K, Downloads: 64"><img src="http://public.gamedev.net/uploads/monthly_06_2011/ccs-8549-0-88485400-1307728985_thumb.gif" id='ipb-attach-img-3048-0-03828100-1330207729' style='width:250;height:151' class='attach' width="250" height="151" alt="Attached Image: Image33.gif" /></a></p><br />
  The problem with the Internet or even LANs is that it is often too slow.  That means that it is important that there is a balance between packet size and speed.  Depending on the game, the server may do more or less.  Some games also use hybrid architectures, where there is a server, but clients don't <em class='bbc'>have</em> to go through the server.  My opinion is to keep it simple, fast, and efficient, and that means use client - server <span style='font-family: Wingdings'>J</span>.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Enough theory, on to WinSock</strong></span><br />
<br />
Okay, there are two versions of WinSock, version 1.1 and version 2.  I suggest using version 2, since you don't have to use TCP/IP.  Now it is time to define what we will accomplish in this article and what not.  We will write a client - server rocks-paper-scissor-shoot game.  The client will be a multi-threaded console application.  The client will be a DirectX Win32 app.<br />
<br />
 I am not a WinSock master and have only learned it a short time ago.  In fact, many things that I am writing about in this article, I am doing for the first time myself!  Still, I believe that this is beneficial, since a WinSock pro may have forgotten what the most common mistakes are and what things are hard to understand in the beginning.  First, I will show you how WinSock is organized, different methods of programming with it, and the prototypes of the API functions.  Once you understand WinSock, we will program Rock, Paper, Scissors, Shoot using WinSock.<br />
<br />
 To begin with, you should say <span style='font-family: Courier New'><span style='color: #000080'>#include</span></span>  at the top of any source file that uses WinSock.  Also, you should add <span style='font-family: Courier New'><span style='color: #000080'>ws2_32.lib</span></span> to any project that uses WinSock.  Now you're all set to program using WinSock, but how about learning how it works and what to do first?<br />
<br />
 There are different ways to program with WinSock.  You can use the very basic UNIX/Berkley type functions, the Microsoft's Windows specialized version of the basic functions, or use the Object Orientated MFC version.  I wanted to go for the OO version first, since classes usually wrap up an API and make it usable.  But no such luck, remember these are MFC classes and that means: make it as complicated as possible.  The MFC classes are just about the same as the very basic UNIX/Berkley functions and Windows extensions put together!  Microsoft's Windows specialized functions are great, but infer that you will be making a Win32 Application by allowing you to hook your sockets to custom Windows Messages that will be sent to your program.  In the case of making a server, this is not true.  Why would we need our server to be a Win32 app?  That's pointless.  To keep it simple we will just use the very basic UNIX/Berkley functions for the server.<br />
<br />
<span style='font-size: 12px;'> <strong class='bbc'>Data types:</strong></span><br />
<br />
<span style='font-family: Courier New'><span style='color: #000080'>sockaddr</span></span><br />
<blockquote><strong class='bbc'>Description:</strong> sockaddr is used to specify a socket connection.  Use sockaddr_in whenever possible, since it is TCP orientated.  This data type is used to store information about a socket (port number, IP address, etc.) that is accepted by a server.  Only a server program uses this data type!</blockquote><span style='font-family: Courier New'><span style='color: #000080'>sockaddr_in</span></span><br />
<blockquote><strong class='bbc'>Description:</strong> sockaddr_in is used to specify a socket connection.  It contains fields to specify IP address and port.  This version of sockaddr is TCP orientated; use it as much as possible.  This type will be used when creating sockets.<br />
<br />
 [indent]<pre class='prettyprint'>struct sockaddr_in<br />{<br />  short sin_family;     	// Protocol type (should be set to AF_INET)<br />  u_short sin_port;     	// Port number of socket<br />  struct in_addr sin_addr;  // IP address<br />  char sin_zero&#91;8&#93;;     	// Unused<br />};</pre>[/indent]</blockquote><span style='font-family: Courier New'><span style='color: #000080'> WSAData</span></span><br />
<blockquote><strong class='bbc'>Description:</strong> WSAData is used when you load and initialize the <span style='font-family: Courier New'><span style='color: #000080'>ws2_32.dll</span></span> library.  This data structure is filled in for you by the <span style='font-family: Courier New'><span style='color: #000080'>WSAStartup ()</span></span> function.  Use this to determine if the computer running your program has the right WinSock version.</blockquote><span style='font-family: Courier New'><span style='color: #000080'>SOCKET</span></span><br />
<blockquote><strong class='bbc'>Description:</strong> SOCKET is a data type used to store socket handles.  These handles are used to identify the socket.  SOCKET actually is nothing more than an <span style='font-family: Courier New'><span style='color: #000080'>unsigned int</span></span>.</blockquote><br />
<br />
<span style='font-size: 18px;'> <strong class='bbc'>The basics</strong></span><br />
 <strong class='bbc'><br />
To load the <span style='font-family: Courier New'><span style='color: #000080'>ws2_32.dll</span></span> use this code:</strong><br />
<br />
 [indent]<pre class='prettyprint'>// Must be done at the beginning of every WinSock program<br />WSADATA w;	// used to store information about WinSock version<br />int error = WSAStartup (0x0202, &w);   // Fill in w<br /><br />if (error)<br />{ // there was an error<br />  return;<br />}<br />if (w.wVersion != 0x0202)<br />{ // wrong WinSock version!<br />  WSACleanup (); // unload ws2_32.dll<br />  return;<br />}</pre>[/indent] You may be wondering what 0x0202 means.  It means version 2.2.  If I wanted version 1.1, I'd change it to 0x0101.  WSAStartup () fills in the WSADATA structure and loads the WinSock2 dynamic link library.  WSACleanup() unloads the WinSock DLL.<br />
<br />
 <strong class='bbc'>To create a socket:</strong><br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s = socket (AF_INET, SOCK_STREAM, 0); // Create socket</pre>[/indent]  That's all you need to create a socket, but you'll have to <em class='bbc'>bind</em> it to a port later when you want to actually use it.  AF_INET is a constant defined somewhere in winsock2.h.  If there is ever a function that requires you to tell it something about the <em class='bbc'>address family</em> (or <span style='font-family: Courier New'><span style='color: #000080'>int af</span></span>), then just say AF_INET.  SOCK_STREAM is a constant that tells Winsock that you want a stream (TCP/IP) socket.  You can also have data gram (UDP) sockets, but they are unreliable.  Leave the last parameter as 0, this will just select the correct protocol for you (which should be TCP/IP).<br />
<br />
 <strong class='bbc'>To actually assign a port to a socket (or <em class='bbc'>bind</em> a socket):</strong><br />
<br />
 [indent]<pre class='prettyprint'>// Note that you should only bind server sockets, not client sockets<br />// SOCKET s is a valid socket<br />// WSAStartup has been called<br /><br />sockaddr_in addr; // the address structure for a TCP socket<br /><br />addr.sin_family = AF_INET;  	// Address family Internet<br />addr.sin_port = htons (5001);   // Assign port 5001 to this socket<br />addr.sin_addr.s_addr = htonl (INADDR_ANY);   // No destination<br />if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)<br />{ // error<br />  WSACleanup ();  // unload WinSock<br />  return;     	// quit<br />}</pre>[/indent] This may look confusing, but it's not that bad.  addr describes our socket by specifying the port.  What about the IP address?  We set that to INADDR_ANY, which allows it to be any IP address, since we don't really care about the IP address if we are just telling WinSock which port we want our side of the connection to be.  Why do we use htons () and htonl ()?  These will convert short and long, respectively, to the correct format for the network to understand.  If we have the port number 7134 (which is a short), then we use htons (7134).  We have to use htonl () on the IP address.  But what if we want to actually specify the IP address?  We don't use htonl (), we use inet_addr ().  For example inet_addr ("129.42.12.241").  inet_addr parses the string and takes out the periods (".") and then converts it into a long.<br />
<br />
 <strong class='bbc'>To listen at the bound port</strong>:<br />
<br />
 [indent]<pre class='prettyprint'>// WSAStartup () has been called<br />// SOCKET s is valid<br />// s has been bound to a port using sockaddr_in sock<br />if (listen(s,5)==SOCKET_ERROR)<br />{ // error!  unable to listen<br />  WSACleanup ();<br />  return;<br />}<br /><br />// listening…</pre>[/indent] Now we just have to <em class='bbc'>accept</em> a connection once some client tries to connect.  The only peculiar thing about the above code is listen (SOCKET s, int backlog).  What is this backlog?  Backlog means the number of clients that can connect while the socket is being used.  That means that these clients will have to wait until all clients before him have been dealt with.  If you specify a backlog of 5 and seven people try to connect, then the last 2 will receive an error message and should try to connect again later.  Usually a backlog between 2 and 10 is good, depending on how many users are expected on a server.<br />
<br />
 <strong class='bbc'>To try and connect to a socket:</strong><br />
<br />
 [indent]<pre class='prettyprint'>// WSAStartup () has been called<br />// SOCKET s is valid<br />// s has been bound to a port using sockaddr_in sock<br />sockaddr_in target;<br /><br />target.sin_family = AF_INET;       	// address family Internet<br />target.sin_port = htons (5001);    	// set server’s port number<br />target.sin_addr.s_addr = inet_addr ("52.123.72.251");  // set server’s IP<br /><br />if (connect(s, target, sizeof(target)) == SOCKET_ERROR)<br />{ // an error connecting has occurred!<br />  WSACleanup ();<br />  return;<br />}</pre>[/indent]  That'sall you have to do to request a connection!  target obviously defines the socket that you are trying to connect to.  The connect () function requires a valid socket (s), the description of the target socket (target), and the size or length of the description (sizeof(target)).  This function will just send a connection request and then wait to be accepted or report any occurring errors.<br />
<br />
 <strong class='bbc'>Accepting a connection:</strong><br />
<br />
 [indent]<pre class='prettyprint'>// WSAStartup () has been called<br />// SOCKET s is valid<br />// s has been bound to a port using sockaddr_in sock<br />// s is listening<br /><br />#define MAX_CLIENTS 5;         	// just used for clearness<br /><br />int number_of_clients = 0;<br />SOCKET client&#91;MAX_CLIENTS&#93;;    	// socket handles to clients<br />sockaddr client_sock&#91;MAX_CLIENTS&#93;; // info on client sockets<br /><br />while (number_of_clients &lt; MAX_CLIENTS) // let MAX_CLIENTS connect<br />{<br />  client&#91;number_of_clients&#93; =  // accept a connection<br />  	accept (s, client_sock&#91;number_of_clients&#93;, &addr_size); <br />  if (client&#91;number_of_clients&#93; == INVALID_SOCKET)<br />  { // error accepting connection<br />	WSACleanup ();<br />	return;<br />  }<br />  else<br />  { // client connected successfully<br />	// start a thread that will communicate with client<br />	startThread (client&#91;number_of_clients&#93;);<br />	number_of_clients++;<br />  }<br />}</pre>[/indent] I hope you can follow that.  MAX_CLIENTS isnÆt really necessary, but I just use it to make the code cleaner and simpler for demonstrative purposes.  number_of_clients is a counter that keeps track of how many clients are connected.  client[MAX_CLIENTS] is an array of SOCKETs which is used to save the handles of the sockets that are connected to the clients.  client_sock[MAX_CLIENTS] is an array of sockaddr that is used to keep information about the type of connection, what port, etc.  Usually, we donÆt want to mess with client_sock, but a bunch of functions will require it as a parameter.  Basically this loop just waits until someone requests a connection, then it accepts it and starts a thread that communicates with the client.<br />
<br />
 <strong class='bbc'>Writing (or sending):</strong><br />
<br />
 [indent]<pre class='prettyprint'>// SOCKET s is initialized<br />char buffer&#91;11&#93;;  // buffer that is 11 characters big<br />sprintf (buffer, "Whatever…");<br /><br />send (s, buffer, sizeof(buffer), 0);</pre>[/indent] Parameter two of send () is const char FAR *buf and it points to the buffer of chars that we wish to send.  Parameter three is an int and it is the length (or size) of the buffer we are sending.  The last parameter is for flags that we will never use; keep it 0.<br />
<br />
 <strong class='bbc'>Reading (or receiving):</strong><br />
<br />
 [indent]<pre class='prettyprint'>// SOCKET s is initialized<br />char buffer&#91;80&#93;; // buffer that is 80 characters big<br /><br />recv (s, buffer, sizeof(buffer), 0);</pre>[/indent] recv () is pretty much the same as send, except that this time, we are not transmitting a buffer, but receiving it.<br />
<br />
 <strong class='bbc'>Resolving an IP address or URL:</strong><br />
<br />
 [indent]<pre class='prettyprint'>// const char *Host contains either a IP address or a domain name<br />u_long addr = inet_addr(Host);   // try and parse it if it is an IP address<br />if (addr == INADDR_NONE) {<br />  // Host isn't an IP address, try using DNS<br />  hostent* HE = gethostbyname(Host);<br />  if (HE == 0) {<br />	// error: Unable to parse!<br />	WSACleanup ();<br />	return;<br />  }<br />  addr = *((u_long*)HE-&gt;h_addr_list&#91;0&#93;);<br />}</pre>[/indent] Although it may be hard to understand at first, the code isn't actually that complicated.  What the code does is try to parse <span style='font-family: Courier New'><span style='color: #000080'>const char *Host</span></span> into <span style='font-family: Courier New'><span style='color: #000080'>u_long addr</span></span>, which we can use to connect to another computer.<br />
<br />
 <strong class='bbc'>To close a socket:</strong><br />
<br />
 [indent]<pre class='prettyprint'>shutdown (s, SD_SEND);  // s cannot send anymore<br /><br />// you should check to see if any last data has arrived here<br /><br />closesocket (s);   // close</pre><br />
[/indent] I know it seems stupid that you must call two functions and then check if any more data has been received to close a socket, but that's life.  <span style='font-family: Courier New'><span style='color: #000080'>shutdown(SOCKET s, int how)</span></span> locks a specific attribute of a socket.  Here are the possible attributes (that are passed in the <span style='font-family: Courier New'><span style='color: #000080'>how</span></span> parameter:<br />
 <ul class='bbc'><li><span style='font-family: Courier New'><span style='color: #000080'>SD_SEND</span></span> means that the socket cannot send anymore</li><li><span style='font-family: Courier New'><span style='color: #000080'>SD_RECEIVE</span></span> means that the socket cannot receive anymore</li><li><span style='font-family: Courier New'><span style='color: #000080'>SD_BOTH</span></span> means that the socket cannot send or receive</li></ul> <br />
<span style='font-size: 18px;'><strong class='bbc'>Blocking, non-blocking, and asynchronous sockets</strong></span><br />
<br />
Here is where I have to stop for a bit and discuss some more theory.  So far we have only been using <em class='bbc'>blocking</em> 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.<br />
<br />
 The next type of socket is the <em class='bbc'>non-blocking</em> 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 <span style='font-family: Courier New'><span style='color: #000080'>while</span></span> 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.<br />
<br />
 <em class='bbc'>Asynchronous sockets</em> 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:<br />
<br />
 [indent]<pre class='prettyprint'>#define WM_ONSOCKET WM_USER+1<br /><br />…in message handler…<br /><br />  case WM_ONSOCKET:<br />  {<br />	if (WSAGETSELECTERROR(lparam))<br />	{<br />  	// error occurred<br />  	WSACleanup ();<br />  	return 0;<br />	}<br />	switch (WSAGETSELECTEVENT(lparam))<br />	{<br />  	case FD_READ: // data has been received<br />    	…<br />  	case FD_CONNECT: // connection has been accepted<br />    	…<br />	}<br />  } break;</pre>[/indent] 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.<br />
<br />
 <span style='font-size: 12px;'><strong class='bbc'>What type of socket should I use now?</strong></span><br />
<br />
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.<br />
<br />
 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.<br />
<br />
 <span style='font-size: 12px;'><strong class='bbc'>Using asynchronous sockets</strong></span><br />
<br />
Alright.  You know how to make blocking sockets and now its time to learn the best client type socket.<br />
<br />
 This is the prototype of the function we're interested in:<br />
<br />
 [indent]<pre class='prettyprint'>int WSAAsyncSelect (SOCKET s, HWND hWnd, usigned int wMsg, long lEvent);</pre>[/indent] 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 <span style='font-family: Wingdings'>J</span>).  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:<br />
<blockquote><span style='font-family: Courier New'><span style='color: #000080'>FD_READ</span></span> - On receiving data<br />
<span style='font-family: Courier New'><span style='color: #000080'>FD_WRITE</span></span> - The socket is ready to send data<br />
<span style='font-family: Courier New'><span style='color: #000080'>FD_CONNECT</span></span> - Server has accepted the socket and we're ready to go<br />
<span style='font-family: Courier New'><span style='color: #000080'>FD_CLOSE</span></span> - The socket has closed</blockquote>  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.<br />
<br />
 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.<br />
<br />
 [indent]<pre class='prettyprint'>#define WM_ONSOCKET WM_USER+1<br /><br />…SOCKET s is initialized.  We will set it to asynchronous mode…<br /><br />WSAAsyncSelect (s, hWnd, WM_ONSOCKET, (FD_READ &#124; FD_CONNECT &#124; FD_CLOSE));<br /><br />…in the event handler…<br /><br />  case WM_ONSOCKET:<br />  {<br />	if (WSAGETSELECTERROR(lparam))<br />	{ // error<br />  	WSACleanup ();<br />  	return 0;<br />	}<br /><br />	switch (WSAGETSELECTEVENT(lparam))<br />	{<br />  	case FD_READ:<br />    	…receive data…<br />  	case FD_CONNECT:<br />    	…start sending data…<br />  	case FD_CLOSE:<br />    	…quit program…<br />  	default:<br />    	…do nothing…<br />	}<br />  } break;</pre>[/indent] Get it?  Notice how only the lparam parameter and not the wparam is used.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Error checking (yuck)</strong></span><br />
<br />
Error checking is very annoying, but <strong class='bbc'>it is necessary in a commercial game</strong>.  Remember that commercial software should be fool-proof and that means a hell of a lot of error checking.  How do I check for errors?  Most WinSock functions return an int.  As a general rule, it is good to say:<br />
<br />
 [indent]<pre class='prettyprint'>if (function(…) == SOCKET_ERROR)<br />{<br />  cout &lt;&lt; "Error!&#092;n";<br />  WSACleanup ();<br />  return;<br />}</pre><br />
 [/indent] Functions that create or accept sockets usually won't return SOCKET_ERROR, but will return INVALID_SOCKET.<br />
<br />
 That was basic error checking... Here is the hard part.  After SOCKET_ERROR or INVALID_SOCKET, and application should call int WSAGetLastError ( void ).  WSAGetLastError will return an error code.<br />
<br />
 WinSock error codes taken from WSAPI22.DOC:<br />
<br />
<table border="1" cellpadding="5" cellspacing="0" width="85%"><tbody><tr bgcolor="#666699"><td width="26%"><font color="white"><b>WinSock code</b></font></td><td width="25%"><font color="white"><b>Berkeley equivalent</b></font></td><td width="8%"><font color="white"><b>Error</b></font></td><td width="41%"><font color="white"><b>Interpretation</b></font></td></tr><tr bgcolor="#DDDDDD"><td>WSAEINTR</td><td>EINTR</td><td>10004</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEBADF</td><td>EBADF</td><td>10009</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEACCES</td><td>EACCES</td><td>10013</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEFAULT</td><td>EFAULT</td><td>10014</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEINVAL</td><td>EINVAL</td><td>10022</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEMFILE</td><td>EMFILE</td><td>10024</td><td>As in standard C</td></tr><tr bgcolor="#DDDDDD"><td>WSAEWOULDBLOCK</td><td>EWOULDBLOCK</td><td>10035</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEINPROGRESS</td><td>EINPROGRESS</td><td>10036</td><td>This error is returned if any WinSock function is called while a blocking function is in progress.</td></tr><tr bgcolor="#DDDDDD"><td>WSAEALREADY</td><td>EALREADY</td><td>10037</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENOTSOCK</td><td>ENOTSOCK</td><td>10038</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEDESTADDRREQ</td><td>EDESTADDRREQ</td><td>10039</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEMSGSIZE</td><td>EMSGSIZE</td><td>10040</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEPROTOTYPE</td><td>EPROTOTYPE</td><td>10041</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENOPROTOOPT</td><td>ENOPROTOOPT</td><td>10042</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEPROTONOSUPPORT</td><td>EPROTONOSUPPORT</td><td>10043</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAESOCKTNOSUPPORT</td><td>ESOCKTNOSUPPORT</td><td>10044</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEOPNOTSUPP</td><td>EOPNOTSUPP</td><td>10045</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEPFNOSUPPORT</td><td>EPFNOSUPPORT</td><td>10046</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEAFNOSUPPORT</td><td>EAFNOSUPPORT</td><td>10047</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEADDRINUSE</td><td>EADDRINUSE</td><td>10048</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEADDRNOTAVAIL</td><td>EADDRNOTAVAIL</td><td>10049</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENETDOWN</td><td>ENETDOWN</td><td>10050</td><td>As in BSD.  This error may be reported at any time if the WinSock implementation detects an underlying failure.</td></tr><tr bgcolor="#DDDDDD"><td>WSAENETUNREACH</td><td><p>ENETUNREACH</p></td><td>10051</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENETRESET</td><td>ENETRESET</td><td>10052</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAECONNABORTED</td><td>ECONNABORTED</td><td>10053</td><td><p>As in BSD</p></td></tr><tr bgcolor="#DDDDDD"><td>WSAECONNRESET</td><td>ECONNRESET</td><td>10054</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENOBUFS</td><td>ENOBUFS</td><td>10055</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEISCONN</td><td>EISCONN</td><td>10056</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENOTCONN</td><td>ENOTCONN</td><td>10057</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAESHUTDOWN</td><td>ESHUTDOWN</td><td>10058</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAETOOMANYREFS</td><td>ETOOMANYREFS</td><td>10059</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAETIMEDOUT</td><td>ETIMEDOUT</td><td>10060</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAECONNREFUSED</td><td>ECONNREFUSED</td><td>10061</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAELOOP</td><td>ELOOP</td><td>10062</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAENAMETOOLONG</td><td>ENAMETOOLONG</td><td>10063</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEHOSTDOWN</td><td>EHOSTDOWN</td><td>10064</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSAEHOSTUNREACH</td><td>EHOSTUNREACH</td><td>10065</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>&nbsp;</td><td>&nbsp;</td><td>Missing 10066 thru 10071</td><td>&nbsp;</td></tr><tr bgcolor="#DDDDDD"><td>WSASYSNOTREADY</td><td>&nbsp;</td><td>10091</td><td>Returned by <b>WSAStartup()</b> indicating that the network subsystem is unusable.</td></tr><tr bgcolor="#DDDDDD"><td>WSAVERNOTSUPPORTED</td><td>&nbsp;</td><td>10092</td><td>Returned by <b>WSAStartup()</b> indicating that the WinSock DLL cannot support this app.</td></tr><tr bgcolor="#DDDDDD"><td>WSANOTINITIALISED</td><td>&nbsp;</td><td>10093</td><td>Returned by any function except <b>WSAStartup()</b> indicating that a successful <b>WSAStartup()</b> has not yet been performed.</td></tr><tr bgcolor="#DDDDDD"><td>WSAEDISCON</td><td>&nbsp;</td><td>100101</td><td>Returned by <b>WSARecv()</b>, <b>WSARecvFrom()</b> to indicate the remote party has initiated a graceful shutdown sequence.</td></tr><tr bgcolor="#DDDDDD"><td>&nbsp;</td><td>&nbsp;</td><td>Missing 10102 thru 10112</td><td>&nbsp;</td></tr><tr bgcolor="#DDDDDD"><td>WSA_OPERATION_ABORTED</td><td>&nbsp;</td><td>*</td><td>An overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in <b>WSAIoctl()</b></td></tr><tr bgcolor="#DDDDDD"><td>WSAHOST_NOT_FOUND</td><td>HOST_NOT_FOUND</td><td>11001</td><td>As in BSD.</td></tr><tr bgcolor="#DDDDDD"><td>WSATRY_AGAIN</td><td>TRY_AGAIN</td><td>11002</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSANO_RECOVERY</td><td>NO_RECOVERY</td><td>11003</td><td>As in BSD</td></tr><tr bgcolor="#DDDDDD"><td>WSANO_DATA</td><td>NO_DATA</td><td>11004</td><td>As in BSD</td></tr></tbody></table>To find detailed descriptions of error codes, look at WSAPI22.DOC (MicrosoftÆs WinSock 2.2 API reference).  So our fool-proof version looks like this:<br />
<br />
 [indent]<pre class='prettyprint'>if (function(…) == SOCKET_ERROR)<br />{<br />  cout &lt;&lt; "Error:&#092;n";<br />  switch (WSAGetLastError ())<br />  {<br />	case …:<br />  	cout &lt;&lt; "this type of error happened!&#092;n";<br />  	break;<br />	case …<br />  }<br />  WSACleanup ();<br />  cout &lt;&lt; "If this error happens again, sue Microsoft!&#092;n";<br />  return;<br />}</pre>[/indent] I know it is a real pain in the neck to do all that error checking, but it is necessary.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>The price you pay for using asynchronous sockets</strong></span><br />
<br />
There is one disadvantage when using asynchronous sockets.  Say you decide to send something to the computer you are connected with, and one command after, you try to perform another operation on the socket, chances are that the socket will return an error.  The error is <span style='font-family: Courier New'><span style='color: #000080'>WSAEWOULDBLOCK</span></span> (error number 10035).  The good news is that this error is not a fatal error, but just means, "Try again later".  The bad news is that in theory, you should be testing for this error specifically and trying to perform your action until it actually works and this error is no longer returned.  Now this is annoying, since you can test for errors by just saying <span style='font-family: Courier New'><span style='color: #000080'>if (socketaction(s)==SOCKET_ERROR)</span></span> (here, <span style='font-family: Courier New'><span style='color: #000080'>socketaction()</span></span> doesn't mean anything.  It is just an example).  But <span style='font-family: Courier New'><span style='color: #000080'>WSAEWOULDBLOCK</span></span> <em class='bbc'>is</em> an error also.  That means you will have to specially test (call <span style='font-family: Courier New'><span style='color: #000080'>WSAGetLastError()</span></span>) if <span style='font-family: Courier New'><span style='color: #000080'>WSAEWOULDBLOCK</span></span> occurs and just repeatedly try again.<br />
<br />
 I have found a cheap way around this which is <em class='bbc'>not</em> 100% guaranteed to work.  When you perform your action and there was an error, test if <span style='font-family: Courier New'><span style='color: #000080'>WSAEWOULDBLOCK</span></span> was returned.  If it was returned then just <span style='font-family: Courier New'><span style='color: #000080'>Sleep (750)</span></span> and try again.  WhatÆs so great about this?  Well, you donÆt have to loop, instead you just delay and try once again.  Chances are, that after 750 milliseconds, the socket will be ready to perform your action.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Rock, Paper, Scissor, Shoot!</strong></span><br />
<br />
Here comes the cool part.  We will program a multiplayer game using WinSock.  The game will be client - server because I find it a more user friendly model than client - client.  We will program two independent applications: RPSS and RPSSS.  RPSS is Rock, Paper, Scissor, Shoot (the client).  RPSSS is Rock, Paper, Scissor, Shoot Server (the server).<br />
<br />
 The server's features are:<br />
 <ul class='bbc'><li>Small, simple, console application</li><li>Lobby type architecture that waits for two clients to join</li><li>Blocking sockets</li></ul> The client's features are:<br />
 <ul class='bbc'><li>Infinite game rounds</li><li>Graphics</li><li>Asynchronous sockets</li></ul> A feature that both the client and the server share is that I have implemented a quit mechanism so if the server realizes that a client has quit, he will also stop the client that is still connected.  This is good since it helps eliminate pointless errors when one client has suddenly quit.<br />
<br />
 We need to develop the protocol we will use to communicate between the two clients and the server.<br />
<br />
 We can just use this:<br />
<br />
 [indent]<pre class='prettyprint'>#define RPSS_NUMOFUSERS 0x03<br />#define RPSS_STARTGAME 0x04<br />#define RPSS_SCISSOR 0x05<br />#define RPSS_ROCK 0x06<br />#define RPSS_PAPER 0x07<br />#define RPSS_QUIT 0x08</pre>[/indent] So each buffer of data that we transmit is 2 bytes long.  The first byte is one of the above commands and the second is a parameter.  For example the first byte we transmit is RPSS_NUMOFUSERS and the second is 2.  If you think about it, the only command that actually needs a parameter is RPSS_NUMOFUSERS, so if we took that away, we would just be transmitting one byte instead of two.<br />
<br />
 In which order should I program client - server games?  I'm trying to figure that out right now!<br />
<br />
 My opinion is:<br />
 <ul class='bbcol decimal'><li>Create the protocol with which client and server will communicate.</li><li>Start coding to the server up to where the connection is accepted.</li><li>Start coding the client up to the part where the server accepts the connection.</li><li>Now code your way, step-by-step, through sending and receiving data for both the client and the server.</li></ul> <br />
<span style='font-size: 18px;'><strong class='bbc'>How to use the demo</strong></span><br />
<br />
The source code and the EXE files for both RPSS and RPSSS are included with this &#100;ocument.  I suggest you start by looking at the source code for RPSSS and then RPSS.<br />
<br />
 Any computer can be the server.  In theory, it should be the fastest computer that also has either a static IP address or a domain name.  For testing purposes, however, it can be any computer.  Start RPSSS.EXE and you will just see a DOS program that does nothing but wait.  You may want to minimize it and do something else.<br />
<br />
 If you want to play, you will need to execute the client (RPSS.EXE).  When you start, you can enter the IP address of the server that you wish to play on.  To adjust the number, use the up or down arrow keys.  To switch to another byte of the IP address, press the left or right arrow keys.  I know this seems overly complicated, but when you actually start the program, you'll understand.<br />
<br />
 When you've entered the IP address, click on the connect button below it.  Now all you have to do is wait for another player and then you can play.  Please note that RPSS.EXE supports Alt-Tab, which means that you can switch between applications.  Using Alt-Tab, you can run two clients and play against yourself (for testing purposes, of course <span style='font-family: Wingdings'>J</span>).<br />
<br />
 When you are actually playing, you will see the different choices of moves in front of you (rock, paper, or scissor).  Select one move using the left or right arrow keys and press enter.  Now you must wait for your opponent to chose.  When both of you have chosen, the score will change and the next round will start.   Press escape or Alt-F4 to quit anytime.<br />
<br />
 Please note that the demo took me about four days to write, so it is not bug-free or user friendly.  It is just mean to demonstrate the proper use of WinSock in a multiplayer game.  There are a few points where I could have improved it, but all-in-all it works.  I can take no responsibility for the demo programs whatsoever!<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>A word on lag (or latency)</strong></span><br />
<br />
Everyone who has played a high-speed multiplayer game has experienced lag.  Whether it was the sluggish frame-rate in GTA2 or the being killed without getting a chance to react in Tom Clancy's: Rainbow Six.  Lag is really annoying, because it doesn't give all players the same chance.  If you have a 56k modem and are playing against someone with a ASDL connection in Korea, and the server is in Korea also, you're bound to experience it.  While your enemy moves lightening fast and is never where you shoot, you hardly move at all and by the time you realize you're being attacked, you're already dead.<br />
<br />
 This may be a reason to develop turn-based or puzzle games.<br />
<br />
 One way around lag is optimization.  Here are a few quick tips:<br />
 <ul class='bbc'><li><strong class='bbc'>Don't</strong> send information every frame.</li><li><strong class='bbc'>Only</strong> send coordinates when you move or change direction.</li><li><strong class='bbc'>Don't </strong>send the entire display, only the parts which have changed.</li><li><strong class='bbc'>Don't</strong> allow more than 32 players at once.</li><li>Players should be able to see an opponent's connection speed (33.6, 56k, ISDN, cable, ASDL, T1, etc.) before choosing to play with the opponent.</li></ul> Even if you consider all the above aspects, you may not be able to get the speed you want or need for the game to run smoothly.  The next step to reducing lag is <em class='bbc'>dead-reckoning</em> algorithms.  Although some algorithms use statistics, others linear equations, others cubic splines, etc., they all work in the same way.  The algorithm will predict what the player's next action is and will use its prediction until a packet has arrived that describes the action that the player actually performed.  A good source for articles on dead-reckoning is <a href='http://www.GameDev.net/' class='bbc_url' title=''>http://www.GameDev.net</a>.<br />
<br />
 The last way around lag that I know of is approximation.  This is basically dead-reckoning, but not quite.  A game that uses this is BaldurÆs Gate.  In the manual it says something like, "If you happen to be situated close to another playerÆs computer, you may notice that you screens appear a little differently.".  This seems to be a good method for multiplayer RPGs.  When you log on to a multiplayer game, the level is transferred to your machine.  When you start playing, all that is ever sent to you are the important actions that a player or NPC has done.  Each computer independently updates its map and some things which depend on a random number will appear differently.  The advantage of this is that since we are only transferring the important data, we are cutting down on the load.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Further reading, last minute stuff, and more, more, more</strong></span><br />
 <br />
<a href='http://www.winsock.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.winsock.com</a><br />
<br />
 <a href='http://www.sockets.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.sockets.com</a><br />
<br />
 There are a number of books about WinSock but I donÆt know a single one since IÆm a cheapskate, just go look it up at <a href='http://www.amazon.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.amazon.com</a>.<br />
<br />
 Read WSAPI22.DOC which is linked to by <a href='http://www.sockets.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.sockets.com</a>.  You may also want to download the WinSock 2 SDK, which, again, is linked to by <a href='http://www.sockets.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.sockets.com</a>.  You should also download the WinSock FAQ from <a href='http://www.sockets.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.sockets.com</a>. <br />
<br />
 My email address is <a href='mailto:ceo@intertainment.8m.com' title='E-mail Link' class='bbc_email'>ceo@intertainment.8m.com</a>, feel free to complain, suggest, or anything else.<br />
<br />
 Copyright ©  2000 Stefan Hajnoczi<br />
<br />
 I take no responsibility whatsoever for this document<br />
<br />
 Use it at your own risk<br />
<br />
 This document is written IMHO]]></description>
		<pubDate>Thu, 15 Jun 2000 12:20:24 +0000</pubDate>
		<guid isPermaLink="false">70431e77d378d760c3c5456519f06efe</guid>
	</item>
	<item>
		<title>Defeating Lag With Cubic Splines</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/defeating-lag-with-cubic-splines-r914</link>
		<description><![CDATA[<em class='bbc'>This article may not be reprinted commercially without the express permission of the author.<br />
Copyright © 2000 Nicholas Van Caldwell <br />
</em><br />
A common problem when writing networked virtual environments is overcoming the lag inherent to the Internet; players seem to jerk about the field of play as new data packets are incorporated. Common solutions include increasing the frequency of packets sent, reducing packet size through compression, and most importantly, dead reckoning. This article will attempt to explain a technique for eliminating the "jerk" of lag by employing the power of cubic splines in a dead-reckoning algorithm.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>What is Dead Reckoning?</strong></span><br />
<br />
Before jumping straight into cubic splines, a brief description of dead reckoning is required. Programmers use this technique to reduce the effects of lag in a game by trying to guess that an object takes. Dead reckoning makes its guess based on the object's characteristics. For example, if an object has a known starting position and velocity then its path can be created using simple physics. The paths created can be applied to the object, creating the illusion of smooth motion. Cubic splines are a kind of dead reckoning that creates a smooth transition between two data points.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Possible Forms of Dead Reckoning</strong></span><br />
<br />
What the programmer wants to do is take a current position for an object and form a smooth path to where the object is supposed to be. Several techniques are available.<br />
<br />
 The most basic form of dead reckoning is the "point-to-point" method. As its name implies, this method involves only moving a player to a new point when a data-packet arrives. Given an average Internet lag of 200-300 ms this creates a noticeably "jerky" player. This method is by far the worst because unless a remote player is absolutely still, his onscreen representation is completely erroneous. The reason for the error is that data packets in a fast quake-style game arrive only 5-10 times per second, while even a slow game updates at 30 frames per second. The only way to make players move smoothly is to send one packet for every game frame. This is a terrible strain on bandwidth, thus the point-to-point updating method is nearly impossible to effectively implement in a real-time game.<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[b254afc47d384bf391bf61c8a786018e]' id='ipb-attach-url-1966-0-07611800-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1966" title="ptop.gif - Size: 2.06K, Downloads: 88"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-30277000-1303371873_thumb.gif" id='ipb-attach-img-1966-0-07611800-1330207729' style='width:200;height:200' class='attach' width="200" height="200" alt="Attached Image: ptop.gif" /></a><br />
<em class='bbc'>NewPosition = OldPosition</em><br />
</p><br />
 The next level of precision is the "linear" method. This method involves creating a straight-line path to the next position. In terms of physics, this means that the velocity of an object is used to decide where it should next appear. This method reduces jitters caused by lag but has a tragic flaw: it assumes people will only move with a constant velocity. Thus, the generated and actual paths vary noticeably (although the game will be much improved over the "point-to-point" method). When playing a game that uses this method, players will seem to move in straight lines. Further, whenever a player starts a new linear path his velocity could change abruptly. The end result is a thoroughly unrealistic game.<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[b254afc47d384bf391bf61c8a786018e]' id='ipb-attach-url-1967-0-07624100-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1967" title="linear.gif - Size: 2.11K, Downloads: 82"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-55924400-1303371911_thumb.gif" id='ipb-attach-img-1967-0-07624100-1330207729' style='width:200;height:200' class='attach' width="200" height="200" alt="Attached Image: linear.gif" /></a><br />
<em class='bbc'>NewPosition = OldPosition + Velocity*Time</em><br />
</p><br />
 A smart programmer might now ask, "why not just add acceleration to your path equations?" Such a method is possible, and will result in even smoother game play. This is called the "quadratic" method because the path created follows a quadratic function. Without detailing the math, this method also fails because even though a player's motion is represented more realistically, his final velocity is likely to be incorrect. This is because quadratic functions do not employ what physicists call "jerk", or the change in acceleration over time. This leads to the final solution: the cubic spline.<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[b254afc47d384bf391bf61c8a786018e]' id='ipb-attach-url-1968-0-07634800-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1968" title="quad.gif - Size: 2.11K, Downloads: 87"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-31294700-1303371934_thumb.gif" id='ipb-attach-img-1968-0-07634800-1330207729' style='width:200;height:200' class='attach' width="200" height="200" alt="Attached Image: quad.gif" /></a><br />
<em class='bbc'>NewPosition = OldPosition + Velocity*Time + Acceleration*(time)<sup class='bbc'>2</sup></em><br />
</p><br />
 Cubic splines offer one of the most realistic methods for creating a dead reckoning path. This is because they account for the starting position&#092;velocity and the ending position&#092;velocity. As a result, objects following a cubic spline path have no jitters, unless lag is especially severe.<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[b254afc47d384bf391bf61c8a786018e]' id='ipb-attach-url-1969-0-07645200-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1969" title="cubic.gif - Size: 2.26K, Downloads: 84"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-81502500-1303371966_thumb.gif" id='ipb-attach-img-1969-0-07645200-1330207729' style='width:200;height:200' class='attach' width="200" height="200" alt="Attached Image: cubic.gif" /></a></p><br />
 <span style='font-size: 18px;'><strong class='bbc'>Using Cubic Splines</strong></span><br />
<br />
Using cubic splines to create a path is a matter of simple algebraic equations. The input for these equations are four (x,y) coordinates. The first coordinate represents the object's starting position. Similarly, the fourth coordinate signifies the object's ending position. Usually the end position is a new (x,y) coordinate that has just arrived in a data packet. The most important coordinates are the second and third; they represent the object's velocity. For the second coordinate, calculate where the object will appear after 1 second with its current velocity. For the third coordinate, reverse the object's end velocity, and calculate where it would appear after 1 second. This is the same as traveling back in time for 1 second (assuming constant velocity). In summary:<br />
 <ul class='bbcol decimal'><li>Coordinate 1  = Starting position   <br /><br />Coordinate 2 = Position after 1 second using starting velocity<br />= Coordinate1 + StartVelocity   <br /><br />Coordinate 3 = Position after 1 second using reversed ending velocity<br />= Coordinate4 – EndVelocity   <br /><br />Coordinate 4 = Ending position</li><li>Here are the parametric equations used to form the spline. <br /><br />x = At<sup class='bbc'>3</sup> + Bt<sup class='bbc'>2</sup> + Ct + D<br />y = Et<sup class='bbc'>3</sup> + Ft<sup class='bbc'>3</sup> + Gt + H<br /><br /> t is the time variable. It ranges from 0 at the initial point to 1 at the end point.</li><li>Formulating the rest of the variables. <br /><br />A = x<sub class='bbc'>3</sub> – 3x<sub class='bbc'>2</sub> +3x<sub class='bbc'>1</sub> – x<sub class='bbc'>0</sub><br />B = 3x<sub class='bbc'>2</sub> – 6x<sub class='bbc'>1</sub> + 3x<sub class='bbc'>0</sub><br />C = 3x<sub class='bbc'>1</sub> – 3x<sub class='bbc'>0</sub><br />D = x<sub class='bbc'>0</sub><br /><br />E = y<sub class='bbc'>3</sub> – 3y<sub class='bbc'>2</sub> +3y<sub class='bbc'>1</sub> – y<sub class='bbc'>0</sub><br />F = 3y<sub class='bbc'>2</sub> – 6y<sub class='bbc'>1</sub> + 3y<sub class='bbc'>0</sub><br />G = 3y<sub class='bbc'>1</sub> – 3y<sub class='bbc'>0</sub><br />H = y<sub class='bbc'>0</sub></li><li>Once the equation is created, the next step is deciding how to implement it in the game. The following method is simple and effective.<ul class='bbcol decimal'><li>Allow an object to move according physical laws (account for velocity and acceleration).</li><li>When a data packet arrives begin creating a spline to the next position.</li><li>Coordinates 1 and 2 of the spline can be found using the current position and velocity. <br /><br />Coord2 = x<sub class='bbc'>old</sub> + v<sub class='bbc'>old</sub></li><li>Coordinates 3 and 4 are more difficult to get. Decide on the number of steps the object will take on the spline before it reaches the final position. Let this number be time T. For coordinate 4, use the new data packet to calculate the final position after t seconds. The same information can be used to calculate the velocity at the new time. <br /><br />Coord3 = x<sub class='bbc'>packet</sub> + v<sub class='bbc'>packet</sub>*t + .5*a<sub class='bbc'>packet</sub>*t<sup class='bbc'>2</sup><br />Coord4 = Coord3 – (V<sub class='bbc'>packet</sub> + a<sub class='bbc'>packet</sub>*t)<br /><br /> This method combines two forms of dead reckoning: a cubic spline, and quadratic motion. The result is more realistic.</li><li>Make the object travel along the spline for T frames.</li><li>At the end of the spline resume at step 1.</li></ul></li></ul> The result will look something like the following:<br />
<br />
 <p class='bbc_center'><a class='resized_img' rel='lightbox[b254afc47d384bf391bf61c8a786018e]' id='ipb-attach-url-1970-0-07655600-1330207729' href="http://www.gamedev.net/index.php?app=core&module=attach&section=attach&attach_rel_module=ccs&attach_id=1970" title="spline.gif - Size: 2.54K, Downloads: 84"><img src="http://public.gamedev.net/uploads/monthly_04_2011/ccs-8549-0-82036600-1303372207_thumb.gif" id='ipb-attach-img-1970-0-07655600-1330207729' style='width:250;height:167' class='attach' width="250" height="167" alt="Attached Image: spline.gif" /></a><br />
</p> <br />
<span style='font-size: 18px;'><strong class='bbc'>Conclusion</strong></span><br />
<br />
This article has covered some of the basics of cubic splines and provided psuedocode for use in any game using 2d Newtonian physics. The provided equations can also be easily extended into use for three-dimensional games. While creating cubic splines is easy, actually implementing them introduces several problems that must be left to the reader to explore on his own.<br />
<br />
 Happy Coding,<br />
<a href='mailto:nvc@mit.edu' title='E-mail Link' class='bbc_email'>Nick Caldwell</a><br />
Massachusetts Institute of Technology<br />
Class of '03]]></description>
		<pubDate>Mon, 14 Feb 2000 22:52:11 +0000</pubDate>
		<guid isPermaLink="false">07a4e20a7bbeeb7a736682b26b16ebe8</guid>
	</item>
	<item>
		<title>Statistical Client Prediction</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/statistical-client-prediction-r876</link>
		<description><![CDATA[<span style='font-size: 18px;'> <strong class='bbc'>Foreword</strong></span><br />
<br />
When Quake World was released by idsoftware back in 1996, introducing the networking technique "Client Prediction" I kept wondering: "How the heck can they predict where I'm going?" I later read about the subject, or Dead Reckoning, as it's also called, and soon discovered that it had nothing to do with chaos theory or destiny. There has already been written articles on this technique (best one is probably at gamasutra.com), so I presume that you are well-informed of it.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>What's your next move?</strong></span><br />
<br />
The technique I am about to explain does exactly what I initially spoke of, that is it <em class='bbc'>guesses your next move</em>. How can it guess? Statistics! Before I go into details with the technical part, let's begin with an example. Say we have a multiplayer football game. Now, it's most likely that you are running towards the ball right? Unless of course your own team has the ball. Then perhaps it was more likely that you ran into position or something. If we make up a ruleset of <em class='bbc'>what is most likely for you to do in a given situation</em> and store it in some kind of statistical database, and then distribute this database out to all playing clients (and perhaps the server), then everyone has the same perception of "common sense". It is now possible for a client to predict the other players most likely move/action, and as long as the other players do things "logically", then there is no need to send out packets are there?<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>What are these statistical data?</strong></span><br />
<br />
There are two ways to gather statistical data. You can either make up a <em class='bbc'>set of rules</em> of what you think is the most likely action in a given situation. A situation is a composite value of all players position/direction/speed/action at a given time. Or, you can <em class='bbc'>record patterns</em> of actions contra situations during gameplay. As some may have guessed this involves the usage of neural networks. Both options are usable. A neural network will definitely be able to see a lot more patterns than the human mind can manage, while a ruleset is much easier to implement and probably requires much less CPU overhead. No matter what, the statistical model has to be distributed to all clients, so they have the same frame of reference.<br />
<br />
<span style='font-size: 18px;'> <br />
<strong class='bbc'>How does it work in practice ?</strong></span><br />
<br />
For each frame (or network tick) you do a for loop through all the other players, and then you (based on the statistical model) predict their next move. You are always presuming that this prediction is what they are really doing, so you set their new position based on it. (Note: you can STILL use the old dead reckoning algorithm, and just put these predictions on top of, as an extra layer.) You also predict your own movement and takes this data and look up against your ACTUAL movement. If these two doesn't match, and if the difference is high enough (perhaps outside a given threshold) you send out a <em class='bbc'>correction packet</em> to all other clients, with your actual position/direction/etc. The other clients will now begin their reckoning on scratch based on your last packet. The benefit is that you don't have to tell the others of your actions as long as you move around logically (as predicted), and with a well trained statistical model you should be able to save a lot of bandwidth usage! Which must be considered the ultimate goal of this technique. The technique is not restricted to human players only, in fact it would be excellent to use with AI players as well, since they already build on some pre-defined set of rules.<br />
<br />
 <br />
<span style='font-size: 18px;'><strong class='bbc'>Why hasn't it been implemented yet?</strong></span><br />
<br />
Perhaps it has, but it is unlikely. I hope you have an idea as how much CPU time the predictions will require from each client. You have to predict each players likely move in each frame on each client. Recording the statistical data can be a complex task as well. I think CPU's eventually will become powerful enough to calculate these amounts of data. Any comments on this article are appreciated!<br />
<br />
 ©Jakob Ramskov 1999<br />
<a href='http://www.ramosa.dk/' class='bbc_url' title='External link' rel='nofollow external'>http://www.ramosa.dk/</a>]]></description>
		<pubDate>Thu, 02 Dec 1999 11:17:48 +0000</pubDate>
		<guid isPermaLink="false">ba9a56ce0a9bfa26e8ed9e10b2cc8f46</guid>
	</item>
	<item>
		<title>Why Pluggable Factories Rock My Multiplayer World</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/why-pluggable-factories-rock-my-multiplayer-world-r841</link>
		<description><![CDATA[<span style='font-size: 18px;'><strong class='bbc'>Introduction</strong></span><br />
<br />
I've developed a nasty habit over the years.  Whenever I come across a business programming article, I instinctively assume that it won't be relevant to anything cool.  My initial reaction is usually "OK, wow, this is great for writing middleware, but probably useless in game programming." <br />
<br />
Most of the time this turns out to be true (when was the last time you used a SQL database to store saved games?), however, there are always a few articles that describe something that can be useful for game programming.  One of those articles recently appeared in the magazine "C++ Report." (<a href='http://www.creport.com' class='bbc_url' title='External link' rel='nofollow external'>http://www.creport.com</a>).  Timothy R. Culp wrote an article entitled <a href='http://www.joopmag.com/html/from_pages/crarticle.asp?ID=1520' class='bbc_url' title='External link' rel='nofollow external'>"Industrial Strength Pluggable Factories."</a>  In it, he describes a very valuable trick, not only in the business world, but in game programming as well. <br />
<br />
This article is an attempt to take Mr. Culp's work and bring it down into the scary mosh pit of game development.  Before continuing, head over to the C++ Report website and read the pluggable factories article.  I'm not going to duplicate what's already been said; I'm going to assume you've read the article and know the basics, and I'm going to dive straight into showing how Pluggable Factories can be used to simplify DirectPlay communications. <br />
<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>The Problem</strong></span><br />
<br />
Networked multiplayer apps today must deal with a wide variety of messages.   There's the standard set of DirectPlay messages (Create Player, Delete Player, Chat, etc.), as well as the army of messages your game needs to communicate.  All of these messages have their own data items, and they all must be able to send themselves through a DirectPlay connection and reassemble themselves on the other side. It's your job as a network game programmer to sort everything out so that your game has an elegant way to send and receive its information. <br />
<br />
The obvious way to do it in C++ is to use classes to represent the different messages.  These classes contain all of the data for a particular message, as well as methods that serialize and deserialize the data into a byte stream (suitable for sending over a DirectPlay connection).  Also, since all of the messages have certain data elements in common (like, who the message was from, and who it's going to), it makes sense to implement an abstract base class and then derive each different message type from it, like so: <br />
<br />
[indent]<pre class='prettyprint'>// the net_message base class<br />class net_message<br />{<br />public:<br />  net_message() { }<br />  ~net_message() { clear(); }<br />  <br />  void clear(void) { }<br /><br />  virtual int serializeto(byte *output) { return(0); } <br />  virtual void serializefrom(byte *fromdata, int datasize) { }<br /><br />  DPID getfrom(void) { return(m_from); }<br />  DPID getto(void)   { return(m_to);   }<br /><br />protected:<br />  <br />  void setfrom(DPID id) { m_from = id; }<br />  void setto(DPID id) { m_to = id; }<br /><br />  DPID m_from;<br />  DPID m_to;<br />};<br /><br />// a specific message derived from the base class – this<br />// example corresponds to DPSYS_CREATEPLAYERORGROUP.<br />class net_message_createplayerorgroup : public net_message<br />{<br />public:<br /><br />  int serializeto(byte *output);<br />  void serializefrom(byte *fromdata, int datasize);<br /><br />  uti_string getplayername(void) { return(m_playername); }<br />  bool isgroup(void) { return(m_isgroup); }<br />  net_byteblob &getdata(void) { return(m_data); }<br /><br />private:<br />  net_byteblob m_data;<br />  uti_string m_playername;<br />  bool m_isgroup;<br />};<br /><br />// convert a directplay message into our class<br />void net_message_createplayerorgroup::serializefrom(byte *fromdata, int datasize)<br />{<br />  LPDPMSG_CREATEPLAYERORGROUP lp = reinterpret_cast(fromdata);<br />    <br />  m_data.setdata(lp-&gt;lpData, lp-&gt;dwDataSize);<br />  m_isgroup = (lp-&gt;dwPlayerType == DPPLAYERTYPE_GROUP);<br />  namestructtoplayer(lp-&gt;dpnName, m_playername);<br />}<br /><br />// another derivation.<br />class net_message_destroyplayerorgroup : public net_message<br />{<br />public:<br /><br />  int serializeto(byte *output) { output = NULL; return(-1); } <br />  void serializefrom(byte *fromdata, int datasize);<br /><br />  uti_string getplayername(void) { return(m_playername); }<br />  bool isgroup(void) { return(m_isgroup); }<br /><br />private:<br /><br />  bool m_isgroup;<br />  uti_string m_playername;<br />  <br />};<br /><br />// convert a directplay message into our class<br />void net_message_destroyplayerorgroup::serializefrom(byte *fromdata, int datasize)<br />{<br />  LPDPMSG_DESTROYPLAYERORGROUP lp = reinterpret_cast(fromdata);<br />    m_isgroup = (lp-&gt;dwPlayerType == DPPLAYERTYPE_GROUP);         	 <br />  namestructtoplayer(lp-&gt;dpnName, m_playername);<br />}</pre>[/indent] Sending these messages isn't a problem û if the client wants to send a certain message, it instantiates the appropriate class, fills up the class with the data it wants to send, and then calls the serializeto() method, which squishes everything into a byte stream, which is then sent using IDirectPlay->Send(). So far, so good.   <br />
<br />
The problem is on the receiving end.  Developing this class-based approach to messaging means that when we receive a message, our program will have to conjure up the appropriate class using nothing but the ID byte contained within the received message.  In other words, our receive code must be able to look at a message and say, "OK, that's ID ___à that's a ____ message, so I need to construct a class of type ____."  Then, we must deserialize the data back into the members of the class. <br />
<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>Why Pluggable Factories Rock</strong></span><br />
<br />
Pluggable factories are a solution to that problem.  Imagine you write a new message class that you want to use in your program.  Now, imagine that you can add support for your custom messages by simply adding the source files to the project.  That's right û you don't change any lines in your networking engineà you simply add your files to the project and recompile. <br />
<br />
Sound too good to be true?  It's not.  Pluggable factories use a few C++ tricks, but it's not rocket science. <br />
<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>Meet Your Maker</strong></span><br />
 [indent]<span style='font-family: Tahoma, Arial'><span style='color: #800040'><em class='bbc'><blockquote>"Blessed are the game programmers, for they shalt not have to deal with legacy file formats."</blockquote></em></span></span>[/indent] The pluggable factory relies on two key C++ tricks: polymorphism (derived classes and virtual functions), and static class members.   <br />
<br />
Let's look at some code.  This code is straight from the networking engine of my upcoming multiplayer puzzle game, Quaternion (see my homepage for more information).  I've called my base pluggable factory net_message_maker; by convention, pluggable factories usually have the word "maker" somewhere in their class name.  This not only quickly tells any programmer what they are, but it also allows us writers to amuse ourselves by creating clever names for the sections of our articles. <br />
<br />
[indent]<pre class='prettyprint'>class net_message_maker<br />{<br />public:<br /><br />  net_message_maker(int type) { <br />	m_registry.insert(std::make_pair(type, this)); <br />  }<br />  static net_message *constructmessage(byte *data, int datasize);<br />protected:<br />  typedef std::map net_message_maker_map;<br />  static net_message_maker_map m_registry;<br />  virtual net_message *makemessage(byte *data, int datasize) const = 0;<br />};</pre><br />
[/indent] For its power, net_message_maker is a fairly simple little class.  The constructmessage() function is the one we're interested in; this function takes a raw byte stream and creates the appropriate net_message derivative instance.  Note that this function is static, so you don't need to actually instantiate a net_message_maker to use it (simply say net_message_maker::constructmessage(à)). <br />
<br />
Notice the makemessage() pure virtual function.  makemessage() is not the same thing as constructmessage(); makemessage() is only implemented in the derivative classes, and is responsible for newing the message and deserializing it. <br />
<br />
We have one constructor, which takes one argument û the type of message (i.e. DPSYS_SESSIONLOST, etc.)  Notice that this constructor simply hands off to the base class constructor, which takes the message type, pairs it with a pointer to itself, and inserts the pair into a map (if you're not familiar with STL, you might want to learn about maps before continuing).  Notice that the map the constructor inserts into û m_registry -- is static, which means it's shared by all classes, and by all derivative classes as well. <br />
<br />
That's all there is to the base maker class.  One static map, one static function, one pure virtual function.   <br />
<br />
Now let's look at a maker derivation.  You'll need to derive a different maker for each message you want to support û you can either use templates, or some old-fashioned #define trickery, or even (horror of horrors) cut and paste to create them. <br />
<br />
[indent]<pre class='prettyprint'>class net_message_createplayerorgroup_maker : public net_message_maker <br />{ <br />public: <br />  net_message_createplayerorgroup_maker() : net_message_maker(DPSYS_CREATEPLAYERORGROUP) { } <br />private: <br />  net_message *makemessage(byte *data, int datasize) const <br />  { <br />	net_message_createplayerorgroup *msg = NULL; <br />	try { <br />  	// construct the appropriate message type<br />  	msg = new net_message_createplayerorgroup; <br />  	// tell the message to populate itself using the byte stream<br />  	msg-&gt;serializefrom(data, datasize); <br />	} catch(...) { <br />  	// handle errors!<br />	} <br />	return(msg); <br />  } <br />  static const net_message_createplayerorgroup_maker m_registerthis; <br />};</pre><br />
[/indent] Notice the m_registerthis variable.  This is one of the tricks Mr. Culp pointed out, and I hinted at eariler. The C++ language says that static members of classes are initialized at program startup.  So, if this code is part of the program when it starts up, the constructor for the m_registerthis variable is going to get called.  The m_registerthis constructor calls the base net_message_maker class constructor, which pairs the this pointer with the ID given (in this case, DPSYS_CREATEPLAYERORGROUP).  We never explicitly use m_registerthis anywhere else in the code; it's sole purpose is to trick the compiler into running the constructor at program startup.  (Granted, if we have multiple static variables, the C++ spec doesn't specify in which order the constructors are called, but that doesn't matter to us). <br />
<br />
What this means is that before the first line of our WinMain() is executed, the m_registry member is going to contain a valid map, linking all registered message_makers to their message IDs.  This is how it's possible to add support for a new message without changing one line of the networking code. <br />
<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>How It Works</strong></span><br />
<br />
Now let's take a look at the heart of the whole system: the function that takes a message ID and returns the appropriate class. <br />
<br />
[indent]<pre class='prettyprint'>net_message *net_message_maker::constructmessage(byte *data, int datasize)<br />{<br />  // cast the raw memory to a generic message to determine its type<br />  LPDPMSG_GENERIC lpMsg = (LPDPMSG_GENERIC)data;<br />  <br />  try {<br />	// find the appropriate factory in the map of factories...<br />	net_message_maker *maker = <br /> 	(*m_registry.find(lpMsg-&gt;dwType)).second;<br />	// use that factory to construct the net_message derivative<br />	return maker-&gt;makemessage(data, datasize);<br />  } catch(...) {<br />	err_printf("net_message_maker::constructmessage: logic error, I don't know<br />            	how to (or can't) construct message ID %d!", lpMsg-&gt;dwType);<br />  }<br />  return(NULL);<br />}</pre><br />
[/indent] Let's say I've just received a big blob of data from DirectPlay's receive function, and now I want to convert that blob of data into the appropriate net_message derivative.  I call net_message_maker::constructmessage(), giving it the blob of data, and the size of the blob of data. <br />
<br />
The first thing constructmessage() does is cast the raw data to a generic message.  This is the sort of "blind casting" that should make any good C++ programmer freeze in terror, but it's a necessary evil.  The DirectX docs even <strong class='bbc'>tell</strong> us to do it this way. <br />
<br />
Once we've cast the blob, we know the type of the message: lpMsg->dwType.  We look in our m_registry variable, and pull out the correct pair.  Then we get the second member of that pair, which is really the this pointer that the constructor registered at program start.  (If we can't find the type, m_registry.find() is going to return NULL (or, in debug, 0xcdcdcdcd), which will generate an exception on the next line, and will land us in the exception handler for the function. Not the cleanest way to do things, but it gets the job done). <br />
<br />
Assuming nothing goes wrong, the local variable "maker" now points to the appropriate factory we should use to construct the message.  We then call the makemessage() function of that factory (we can do so, because we have access to the private methods of other instances of ourselves).  makemessage() is a pure virtual function, so we'll end up inside of the appropriate maker. <br />
<br />
makemessage() news up the appropriate net_message derivative, and then tells that instance to deserialize itself from the provided byte blob.  Now we have a perfect net_message, all ready to go. <br />
<br />
From here, you can do whatever you want.  Maybe your networking system is like mine, and stores all of the incoming messages in a vectorà or maybe you've got some thread action happening, and have a secondary thread processing the messages.   That really doesn't matter û what matters is that with one simple function call, constructmessage(), you've transformed a byte blob into a C++ class. <br />
<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>Conclusion</strong></span><br />
<br />
Congratulations, you now know about pluggable factories.  Keep in mind that this technique, as Mr. Culp explains, isn't just for networking messages.  Basically any place in your code where you need to turn an ID byte into a class is a great place for pluggable factories.  There's a lot more power contained in this pattern than I'm illustrating; the purpose of this article was to show you how to apply a theoretical concept directly to your code. <br />
<br />
And, just maybe, to make you think twice before you cast off that "business programming journal" as useless. <img src='http://public.gamedev.net/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' /> <br />
<hr class='bbc' /><em class='bbc'>Mason McCuskey is the leader of <a href='http://www.spin-studios.com' class='bbc_url' title='External link' rel='nofollow external'>Spin Studios</a>, an indie development group looking to break into the industry by creating a great game, Quaternion, and getting it published.  He can be reached via the Spin Studios website (<a href='http://www.spin-studios.com' class='bbc_url' title='External link' rel='nofollow external'>http://www.spin-studios.com</a>), and doesn't mind answering your questions by email at <a href='mailto:mason@spin-studios.com' title='E-mail Link' class='bbc_email'>mason@spin-studios.com</a>.</em>]]></description>
		<pubDate>Wed, 10 Nov 1999 17:19:53 +0000</pubDate>
		<guid isPermaLink="false">e8dfff4676a47048d6f0c4ef899593dd</guid>
	</item>
	<item>
		<title>The Essentials of Multiplayer Games</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/the-essentials-of-multiplayer-games-r722</link>
		<description><![CDATA[<p class='bbc_left'><strong class='bbc'><span style='font-size: 18px;'>or, "Some categorization, problems, solutions, general stuff about multiplayer-games" </span></strong><br />
</p><br />
There are a few distinct flavors of multiplayer games, all of which require different approaches. On one hand, there're games written for many players, but designed to be played on a single machine. On the other, there are games written for local play, or in general, gameplay across more than one machine with a local connection not reliant on a network (like a null modem cable or dial-up modem game). Finally, there are games which take place over large, wide-area networks. I shall refer to these as single-machine, local, and networked multiplayer games, respectively, from here on in.<br />
<br />
 In single-machine multiplayer games, the main game loop must call the engine to process each player involved in the game; this includes getting input from them, moving them, rendering their view, and computing any other logic associated with them in the game. In a local multiplayer game, the game loop only needs to process one player, the player on the machine which the game is running, then send information about the player out to the other machines and accept information about the other players (if needed) in return. Networked multiplayer games are similar to local multiplayer games, but a client/server model is generally used whereby each machine transmits its data to one server, then gets information about other players back from the server.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Single-machine multiplayer games</strong></span><br />
<br />
When designing single-machine multiplayer games, which are not very common on PCs these days, you must take into account several questions. The most important of these would be, "How is each player going to be getting input to the game?" and "How is each player going to see their character move, with only one screen?".<br />
<br />
 Some common approaches include using two input devices, such as a joystick and a keyboard, or sharing one input device, such as two people using one keyboard (there would have to be seperate keys for every action for every player). Trying to share an input device is a very outdated approach, and I'm pretty sure that the gaming community got sick of it early on.<br />
<br />
 There have been a few more worthy approaches to the display problem. Most single-machine-many-players-at-the-same-time games simply let players share the same view. As a rule, this will work well only if the view isn't first person, and only if (for 3D games) camera control is independent of player positions. In the old side-scroller days, we sometimes saw split screens, wherein each player's view was rendered on a different half of the screen. Split-screens are a big drag on rendering time for any kind of game, and they definitely can make a game cumbersome, but they do work.<br />
<br />
 About the most effective approach to the display and input problems associated with one-machine mulitplayer games, at least for PCs, is to use a turn-based system. Considering that they're still actually implemented, I'd say that turn-based systems have had the most luck over the ages. Turn-based systems work by switching between player and player and allowing only one player to play at a time.<br />
<br />
 [indent]<pre class='prettyprint'>//A turn-based thingy<br /><br />//somewhere in a header<br />player *cur_player;<br /><br />.....<br /><br />//somewhere in some source file<br />void switch_player(player *p) {<br /> 	cur_player = p;<br /> 	switch_level(p-&gt;level);<br />.....<br /><br />//in the main loop<br />move((player *)&cur_player);</pre>[/indent] Anyone that can write a single-player game and has an understanding of scalable design knows enough to write a single-machine multiplayer game. Because I've covered scalability, and I assume that you can write a game (as a game programmer...), you can write one, if you'd like. I suspect that you wouldn't like to; you're probably more interested in networked games.<br />
<br />
 Single-machine multiplayer PC games are becoming progressively more extinct, but I find it fit to note that old single-machine techniques aren't useless. Consoles, mind you, are still very big on one-machine multiplayer.<br />
<blockquote><table align="center" border="1" cellpadding="5" width="90%"><tbody><tr><td bgcolor="#CCCCFF">Opinion: Turn-based systems and one-machine single-player games in general are acceptable for "the other" gaming market, that wants to remember what the Atari felt like when they used to pull it out of the closet every other Saturday, but hard-core gamers on modern consoles should be ashamed of it. Hardcore PC gamers might even loathe it, because "MyMachineOnlyMonopoly" is averting the one big advantage of the PC as a gaming platform over everything else; networking, networking, networking. The multiplayer game market paradigm shifted towards interactivity a long, long time ago, and is presently shifting towards networking. Don't overlook it.</td></tr></tbody></table></blockquote><span style='font-size: 18px;'><strong class='bbc'><br />
Local multiplayer games</strong></span><br />
<br />
 Local multiplayer games have been around for quite some time. Support for null-modem play is still very common in today's games. On the contrary, direct machine-to-machine modem connections are a lot less popular than they once were, due to the fact that it gets a bit limiting facing the phone charges associated with long-distance modem calls.<br />
<br />
 The architecture of a local multiplayer game is fairly simple. Each machine is responsible for updating the game for one player. Each machine then stores the changes in player state in a <em class='bbc'>packet</em> (a packet is data with a header to be transmitted across a connection), which is sent to the other machines. The other machines in the game use this data to update their game-state, and send out information about their own players' movements, and the cycle continues.<br />
<br />
 Obviously, the specific implementation of this scheme is different between different games: In realtime games, asynchronous packet transmission is a must, and the game has to stay synchronized even if data packets are missed. In non-realtime games, you can rely on sending and receiving packets at a definite time, and you also don't have to worry about overburdening your data stream.<br />
<br />
 So here's a basic recepie for a local multiplayer game. First, you establish a connection to the other machine(s) in the game. This shouldn't be too hard, considering that a phyisical one (such as a LAN or a null-modem cable, or a direct phone line [modem]) must exist for your game to be considered "local". Then, you somehow negotiate the initial setup of the game. Finally, the game begins, and you begin the data-transfer process just described. Then, of course, you close the "connection". It's conceptually simple.<br />
<br />
Here's some code to convey all of this, and a bit more (a very simple example).<br />
<br />
 [indent]<pre class='prettyprint'>//pseudo-code<br /><br />#define NEW_GAME    	2<br />#define LEAVING_GAME	4<br />#define SOMETHING   	8<br />#define RESET       	16<br /><br />#define ESCAPE_SEQUENCE 0xFFFFFFFF<br /><br />#define MAX_QUEUE   	16<br />#define MAX_BUFFER  	256<br /><br />typedef struct {<br />int obj,x,y,z,frame;  //none of these can be 0xffffffff<br />input_status i;   	//no elements of this can be 0xffffffff<br />unsigned char flags;  //can't = 255 (0xFF)<br />int magic;        	//always 0xFFFFFFFF to indicate the end of the packet<br />} game_packet;<br /><br />game_packet queue&#91;MAX_QUEUE&#93;;<br />int cur_queue=0, unprocessed_packets=0;<br />int sync_err=0, packets_lost=0; //sync_err is a reserved flag for major<br />                            	//synchronozation errors<br /><br />unsigned char serial_buffer&#91;MAX_BUFFER&#93;;<br />int cur_buf=0, last=0;<br /><br />//read this carefully (regarding an imaginary interrupt handler x):<br /><br />//how it works:<br />//interrupt-handler x is called when a character is received from the<br />//serial buffer.  The interrupt handler sets serial_buffer&#91;cur_buf&#93; to the<br />//character received, increments cur_buf, and performs any necessary bounding<br />//work (making sure that cur_buf x also tracks<br />//packet-boundaries; if the last character received was 0xFF and the current<br />//is also 0xFF, then x will increment the global "last".  Last is tested at<br />//the end of the ISR;  when last reaches 3, queue&#91;cur_queue&#93; will be filled<br />//with the last sizeof(packet)-1 bytes in the serial buffer along with the<br />//current character, unprocessed_packets will be incremented, last will be<br />//set to 0, cur_buf will be set to 0, and cur_queue will be incremented.  If<br />//cur_queue &gt; MAX_QUEUE, cur_queue is set to 0 and this entry is used to fill<br />//the packet; packets_lost is also incremented by 1, and unprocessed_packets<br />//is set to 1.<br /><br />//what that does:<br />//it reads characters from the serial buffer, and when there's a complete<br />//packet, it fills one element of a recycling queue with the packet<br /><br />...<br /><br />void Send_Packet(game_packet *p) {<br />  ...<br />  Send_Out_Serial(open_port, p-&gt;obj);<br />  Send_Out_Serial(open_port, p-&gt;x);<br />  Send_Out_Serial(open_port, p-&gt;y);<br />  Send_Out_Serial(open_port, p-&gt;z);<br />  ...<br />}<br /><br />void Process_Packets(packet *p) {<br />  ...<br />  if(!unprocessed_packets) //no new packets to process, so return<br />	return;<br /><br />  asm cli<br /><br />  for (int index=cur_queue-(unprocessed_packets-1);index &lt;unprocessed_packets;index++) {<br />	Update_Game(queue&#91;index&#93;);<br />  }<br /><br />  cur_queue = 0;<br />  unprocessed_packets = 0;<br /><br />  asm sti<br />  ...<br />}<br /><br />//Process_Packets would be called in the main game loop at a certain<br />//point.  If everything is running okay, the error-handling "features"<br />//built into it and interrupt-handler x shouldn't have to take over.<br /><br />void Init_Game(int port) { //where port is a serial port<br />                     	//connected to another machine<br />  game_packet init;<br /><br />  init.flags = NEW_GAME &#124; RESET;<br />  Send_Packet(port, (game_packet*)&init);<br />  Init_Local_Game();<br />}<br /><br />...<br /><br />//You get the idea?</pre><br />
[/indent]<strong class='bbc'><span style='font-size: 18px;'>Networked multiplayer games: Internet intro ala crash-course </span></strong><span style='font-size: 18px;'><span style='font-size: 10px;'><blockquote></span></span><table align="center" border="1" cellpadding="5" width="90%"><tbody><tr><td bgcolor="#FFCCCC">RANT: These are the real hot topics these days in the multiplayer game world. Networked multiplayer games can be really, really cool. No longer are you playing a game with your friend sitting in the chair next to you, trying to figure out whose character just moved, no longer are you playing a game against some half-witted FSM, you're playing against a <b>REAL PERSON</b> and you can <i>tell</i>.<br />
<br />
Gamers today don't want to simply interact with their games by moving a little model around, and could care less whether or not you used quaternion-based interpolation between keyframes coupled with skeletal-hierarchy animation for your two-hundred polygon optimized character with hardware bilinear-filtered perspective-correct texture mapping applied and high-end LOD processing. Rather, they want to take interaction to a higher level, whether this higher level is achieved via outstanding scene-realism or any other means. The influx of networked-multiplayer games is an exciting manifestation of this.</td></tr></tbody></table><span style='font-size: 18px;'><span style='font-size: 10px;'></blockquote></span></span>Networked multiplayer games are conceptually the same as  local-multiplayer games, with a few exceptions. First of all, each  machine in the game still handles processing for the player using it.  However, instead of sending packets out to all of the other players in  the game (or just the other player), in a networked game, machines send  packets to one central <em class='bbc'>server</em> and receive packets from the server  in return. The server is at the center of the game, storing all the  game's information and keeping things running. If turn-based systems are  used somehow, then the server is responsible for managing them. All the  machines connected to the game's server are called clients. This model  in general is called the client-server model of communication.  Client-server is <span class='bbc_underline'>the</span> communications model used in the real world, so get used to it.<br />
<blockquote><table align="center" border="1" cellpadding="5" width="90%"><tbody><tr><td bgcolor="#CCCCFF">There are many books on client-server and other networking concepts...see <a href="http://www.developer.com/reference/r_servers.html">http://www.developer.com/reference/r_servers.html</a> for a great online collection.</td></tr></tbody></table></blockquote>Networks implement communication protocols in order to give meaning  and structure to communications taking place on them. All communications  on a network are carried out according to a standard set of these  protocols; if you are to use a network effectively, then you must use  its communications protocols. The Internet has TCP/IP (Transmission  Control Protocol/Internet Protocol) to serve this purpose. TCP/IP is a  family of protocols, both application-level (i.e., high-level, like FTP,  HTTP, Gopher) and network-level protocols (such as IP, ARP, ICMP). In  TCP/IP, packets are constructed and routed through the network to the  appropriate machine, based upon the headers of these packets. The  data-area of these packets is the acceptable place for you to put your  game's data (you don't have to handle packets quite as was done above).  The Internet gaurantees that your packets will be sent to the correct  machine, that is, the machine running the server. Client applications, or the version of the game that you would  distribute to your end-users (this program is often called the  "client"), send TCP/IP packets to the server, a program that dissects  them and processes them; the server is a program that runs on a machine  identified by an IP address. The server listens to a TCP/IP "port",  where data comes in, and sends data back to its clients via TCP/IP.<br />
<br />
 For the amateur, client/server based games can present a lot of  problems, when one tries to take them on from the ground up: First of  all, you need a dedicated machine with a dedicated IP to run the server.  Next on the list, the machine has to be able to actually run the  server: Many commercial end-user operating systems like Windows 95 don't ship with TCP/IP server implementations. Fortunately, there are solutions such as Linux...<br />
<br />
 There's a lot involved in sending and processing a single packet of  data in networked games. Fortunately, in most operating systems, we've  got access to TCP/IP client implementations that allow us to avert the  technicalities of low-level Internet communication. With Winsock, for  instance, it's possible to come up with programs that do things like  retrieve web pages from port 80 on any machine, in about a page of code. High-level operating system APIs for Internet functions are a blessing, not a hurdle, despite what  the complaints may register. After all, is it really practical to  implement around thirty years of Internet yourself?<br />
<br />
<strong class='bbc'><span style='font-size: 18px;'>That's all for now</span></strong><br />
<br />
Hopefully, this article has helped you understand the essentials of  multiplayer game programming. If you didn't understand it, go back and  read through it again; this was designed to be a practical introduction  that would allow you to go write some multiplayer games as soon as  possible. Anyway, happy coding, and finish that game! <img src='http://public.gamedev.net/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' /><br />
<br />
]]></description>
		<pubDate>Wed, 15 Sep 1999 16:18:23 +0000</pubDate>
		<guid isPermaLink="false">404dcc91b2aeaa7caa47487d1483e48a</guid>
	</item>
	<item>
		<title>Introduction: Designing Multiplayer Games</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/introduction-designing-multiplayer-games-r721</link>
		<description><![CDATA[<span style='font-size: 18px;'><strong class='bbc'>or, "a crash course in scalable design that centers around multiplayer games" </strong></span><br />
<br />
 Multiplayer games are a logical extension of single player games; for the most part, they make use of the same constructs, the same methods, and involve the same general concepts as any other games. The only difference is that the engine for a multiplayer game has to be able to handle more than one player at a time. If your engine is truly scalable, there shouldn't be a problem moving from single-player to multiplayer. On the other hand, if you make a lot of assumptions, then you're going to have trouble.<br />
<br />
 What does "scalable" mean in terms of a game engine? For our purposes, it means that the engine can be extended to function for many different cases with little trouble. Example of game-engine scalability: When you plot a pixel, do you assume that you're plotting at a certain resolution all the time? With that answer in mind, what if was to demand that you allow the player to be able to change the resolution during game play? If you answered, "yes, I assume that the screen has certain dimensions all the time," then it's going to require some better design thinking to get your putpixel working under different resolutions. On the other hand, a good design will intrinsicly allow this.<br />
<br />
 So take a look at your fundamental design assumptions in a single player game. How do you store information about the player, such as their position? Do you just slop it into globals? C++ doesn't make you immune to bad design, either--do you just slop the position of the player into private members of your game's "engine" class, or however you've got it worked out? When the right arrow is pressed, do you just add a velocity to some player_x variable?<br />
<br />
 It sounds trivial, but these issues all present problems when you want to make a single player game multiplayer. So here's a general solution: When you're designing the very foundation of your entire game logic, move all of your information about a player into a structure or a class, and use *that* to represent a player, not global variables. Treat a player like a polygon in your good-ol'-software-3D-engine-that-you-wrote-two-years-back-with-only-stone-tablets-in-Ancient-Greek-for-a-reference; you need to be able to represent a single player in a general fashion so that your engine can process any player.<br />
<br />
 For instance, let's consider a really simple side-scroller that must be designed to let two people play the same game on one machine. We might say that a player is:<br />
<br />
 [indent]<pre class='prettyprint'>#define KEYBOARD   0<br />#define JOYSTICK   1<br />#define MOUSE 	2<br />#define BRAIN 	3<br /><br />typedef struct {<br />int x, y, xv, yv;<br />int input_device;<br />sprite *player_sprite;<br />} player;</pre>[/indent] [You want to consider that different players might be using different input devices; this is accounted for with the input_device member of the player structure and the constants that it can be set to.]<br />
<br />
 In our strictly-two-player one-screen hypothetical game, we might then define two "player" structs for both of our players as globals, like this:<br />
<br />
 [indent]<pre class='prettyprint'>player players&#91;2&#93;;</pre>[/indent] Then in our main game loop, when we want to draw the players, we simply do this:<br />
<br />
 [indent]<pre class='prettyprint'>draw_sprite(player&#91;0&#93;.player_sprite);<br />draw_sprite(player&#91;1&#93;.player_sprite);</pre>[/indent] When we move the players, we simply do this:<br />
<br />
 [indent]<pre class='prettyprint'>move((player*)&player&#91;0&#93;);<br />move((player*)&player&#91;1&#93;);</pre><br />
[/indent] Getting input from the players would be a bit more complicated, but still simple if we want to think in terms of making the game scalable. Remember that different players might be using different input devices; see above.<br />
<br />
 The only thing that's different between these input devices is how they get information to the game: The information that different input devices relay to a game is actually telling you the same thing. So just define a structure that describes what an input device is telling the game. This structure can then be reused for all input devices. Like this:<br />
<br />
 [indent]<pre class='prettyprint'>typedef struct {<br />    char move_left, move_right, move_up, move_down, fire;<br />} input;</pre>[/indent] Then, write seperate functions to process input from each kind of input device:<br />
<br />
 [indent]<pre class='prettyprint'>void keyboard(input *i) {<br />   ...<br />   if (key_down&#91;KEY_LEFT&#93;)<br />  	i-&gt;move_left = 1;<br />   if (key_up&#91;KEY_LEFT&#93;)<br />  	i-&gt;move_left = 0;<br />   if (key_down&#91;ENTER&#93;)<br />  	i-&gt;fire = 1;<br />   ...<br />}<br /><br />void joystick(input *i) {<br />   ...<br />   if (button_down)<br />  	i-&gt;fire = 1;<br />   if (button_up)<br />  	i-&gt;fire = 0;<br />   ...<br />}</pre>[/indent] And then you can just use one master function to handle all of the input for each player:<br />
<br />
 [indent]<pre class='prettyprint'>void get_input(player *p) {<br />   input i;<br /><br />   switch (p-&gt;input_device) {<br />      	case KEYBOARD:<br />   			keyboard((input *)&i);<br />   			break;<br />      	case JOYSTICK:<br />   			joystick((input *)&i);<br />   			break;<br />      	...<br />      	default:<br />   			if (!known_device((input *)&i, p-&gt;input_device)) {<br />   			game_error(NO_INPUT_DEVICE);<br />   			return;<br />   }<br /><br />   if(i-&gt;move_right)<br /> 	p-&gt;x += p-&gt;xv;<br />   if(i-&gt;move_left)<br /> 	p-&gt;x -= p-&gt;xv;<br />   ...<br />}</pre>[/indent] [the known_device() function would move through a list of specialty devices or something and do any special processing, returning 0 if the device doesn't exist at all or 1 if it did indeed process it and get input]<br />
<br />
 Then back in your main game loop, just do this:<br />
<br />
 [indent]<pre class='prettyprint'>get_input((player *)&players&#91;0&#93;);<br />get_input((player *)&players&#91;1&#93;);</pre><br />
[/indent] Already, some of the benefits of scalable game engine design should be obvious to you. By simply generalizing a few fundamental assumptions that have been made, we've already figured out how to perform a few simple tasks involved in a multiplayer game, and we've also given ourselves the ability to change aspects of a player during real-time that come in handy even in a single player game.<br />
<br />
 For instance, let's say that your player's sprite in your little 2D game is a ship. Well, what if you want them to be able to choose from among a selection of ships? Simple, you just change the player_sprite member of their information structure. What if you want each ship to have different motion characteristics? Simple, you just add information that makes up the physics model for a given ship to the player's player structure, and set the fields appropriately when the player selects a given ship. What about if the player wants to switch from one input device to another in the middle of the game? Simple, just set the input_device field of their player structure to the input device that they want to use.<br />
<br />
 Stating the obvious: A large part of the complexity involved in moving your game to a multiplayer setting is simply a matter of <span class='bbc_underline'>resolving</span> <span class='bbc_underline'>scalability</span> <span class='bbc_underline'>issues</span> in your game engine's <strong class='bbc'>fundamental design</strong>.<br />
<br />
 To extend this skin-and-bones-multiplayer-game-on-a-single-machine model that was just developed above, let's ask ourselves more questions, to eliminate more fundamental assumptions that we're making. First of all, it should become obvious that the model above applies only in simple, two player games, right? As is, it would seem so. But for the heck of it, let's pretend that we're developing for a console that allows up to four players at once.<br />
<br />
 [indent]<pre class='prettyprint'>#define MAX_PLAYERS  4</pre>[/indent] We'd like to be able to support four players, because the console offers paddles for that number of people, and we want our game to sell based on it's ability to utilize cool features. Okay, so all we really have to do is come up with a global variable,<br />
<br />
 [indent]<pre class='prettyprint'>int num_players;</pre>[/indent] >Then create MAX_PLAYERS player information structs for use in the game,<br />
<br />
 [indent]<pre class='prettyprint'>player players&#91;MAX_PLAYERS&#93;;</pre>[/indent] and then process all the players in our main game loop instead of just two. This can be accomplished with simple for loops:<br />
<br />
 <pre class='prettyprint'>for (int index=0; index &lt;max_players; index++)="" move((player="" *)&player&#91;index&#93;);="" </pre><em class='bbc'>(Ed Note: the above code may have been improperly formatted in the original article. This is the best version that could be pulled from the page source)</em><br />
<br />
Because we were careful to design our functions which receive input  and so forth scalably, we can seamlessly extend the game in a manner of  no time whatsoever. All we have to do is write input device functions  that work for PADDLE_1, PADDLE_2, and so forth. Now what if we want to be able to support an arbitrary number of  players? Let's say that there's this cool new extender device for our  imaginary console machine, that allows one to hook up as many paddles as  they want. We can simply extend our limit up to a certain level that  really should never be reached, or we can use a linked list of players  and make no assumptions. (read: be scalable)<br />
<blockquote><table border="1" cellpadding="5" width="75%"><tbody><tr><td bgcolor="#CCCCCC">For those of you that don't know what a linked list is, it's really simple. A linked list is a chain. Each link in a linked list contains some data or a pointer to some data, and a pointer to the next link. Each link on the chain is called a node. The first link on the chain is called the head. So it's like this:<blockquote><span style='font-family: Courier New'>typedef struct {<br />
int data;<br />
void *next;<br />
} node;<br />
<br />
node head;</span><br />
</blockquote><p>So (node *)head->next = the next node on the linked list.</p><p>When you follow the next pointers of each node on the linked list until you reach a node who has no next pointer (node->next = NULL), and process the data on each node as you go, you are said to be walking, or transversing, the linked list.</p></td></tr></tbody></table></blockquote>This would allow us to extend the number of players or decrease the  number of players at run time, by simply adding nodes to [malloc] or  removing nodes from [free] the linked list. All you'd have to do is walk  the linked list of players and process each one within the game's main  loop. The number of players would be limited only by the amount of  avaialble memory on the machine running the game.<br />
<br />
 In yet another scenario, what if someone comes along and adds a  really cool new input device to the platform that you're writing this  game for, and it's only a week before you ship? Well, assuming that you  can write a driver for the thing or pull support code from somewhere,  and do it fast, with the scalable design just given above, you can  integrate it seamlessly.<br />
<br />
 Once again, it pays off to design your engine well. I didn't pull the  situations above out of my hat--these things happen. Good design  becomes exponentially more important with the complexity of your game,  and may mean the difference between a few days work porting code, or a  few days work adding features, and a weekend adding features. When your  game becomes multiplayer, the durability of your engine is tested. So  design it to be tough, design it to be scalable.<br />
<br />
 So hopefully, you've learned something about scalability as it  relates to designing a multiplayer game. The key to extensibility is  good design: Good design always, always, always pays off. Either take my  word for it, or try it and take your own.<br />
<br />
 Good luck, happy coding, and finish that game.]]></description>
		<pubDate>Tue, 14 Sep 1999 19:35:34 +0000</pubDate>
		<guid isPermaLink="false">28dc6b0e1b33769b4b94685e4f4d1e5c</guid>
	</item>
	<item>
		<title>What is Lag?</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/what-is-lag-r712</link>
		<description><![CDATA[Lag is the bane of Internet gameplay, but what is it?<br />
<br />
 Latency is the proper name for the time it takes a packet of information to be sent from the sender to the receiver over a network. Lag is what is it generally called and more specifically when it is noticeable. If the latency is low, you don't notice any lag, the longer it takes a packet to cross the network, the more lag you have.<br />
<br />
 To understand why you have lag you need to understand how information is sent.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>The Packet</strong></span><br />
<br />
When information needs to be sent from your computer it first needs to be chopped up into small pieces, these pieces are called packets. Your computer cant send all its information at once because you cant be guaranteed that no one else will try to send information at the same time and cut off your transmission. Basically networks or any type of computer connection work just like a phone conversation you would have with a friend. If you both talk at the same time, it's hard to understand what is being said clearly. If one of you talks and the other listens, then it's easy to understand what each other is saying.<br />
<br />
 One of the key things to understand about packets is that the longer the packets are, the longer it will take to send and the more likely you will be interrupted by someone else. If you are interrupted you have to wait for a little while, in which the network controller hopes the interrupting transmission has finished, and then you send the packet again. When another packet interrupts your packet it is called a collision.<br />
<br />
 The more often you have collisions, the more lag you will have and collisions are extremely common on the Internet as you have billions of packets of information being sent all over the world, all the time.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>The Ping</strong></span><br />
<br />
A "ping" is both a term and a program used to determine how quickly a packet can go to the destination and the destination can send a response back that it got the packet, so it is measuring a round trip of information. Ping times vary tremendously by what type of connection you have to your network, how close you are to your destination and how much other information is trying to be sent by other people at the same time.<br />
<br />
 On a Local Area Network (LAN), that is a system of computers tied together all in one basic location like a house or office, you can receive extremely fast responses, usually less then 10 milliseconds if there is not a lot of transfers happening. In an environment like this you will probably never notice a lag unless someone starts doing one or more huge file transfers.<br />
<br />
 If you are connecting to the Internet through a dial-in modem to an ISP (Internet Server Provider), as most home users are, then you will receive much higher ping times because your connection is hundreds of times slower than a LAN. Games are however usually designed so that they will still work well on a dial-up Internet connection, but there are a lot of factors that go in to the connection moving smoothly.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Connection Speed</strong></span><br />
<br />
The first thing that will limit your network connection is the speed at which your computer can talk to your ISP. Most modems today are at least 28.8K BAUD to 56K BAUD. BAUD means bits per second, and does not stand for anything, it was named after an engineer name Baudot. A bit is one switch that is either "on" or "off". To have enough information for a single character you need 8 bits, which equal a byte. However, because you are sending the information over a modem, you have to add on extra information so that the receiver knows he is listening to you correctly, so it actually takes 10 bits to send 1 byte. This makes calculating how many bytes you are sending easy however, as you just need to divide 28800 bits/second (28.8K BAUD) by 10 and end up with 2880 bytes per second.<br />
<br />
 Although you may have a modem that say it is a 56K BAUD modem, it is unlikely you will ever receive rates higher than about 3400 bytes per second. When you do receive more it is usually because your modem is compressing the information sent, and when you download information that is already compressed or is not very compressible, you will not get those extra bursts of speed above about 3400 bytes/second.<br />
<br />
 Enough of the history lesson, lets get into where this matters: the lag.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Birth of Lag: Building the Packet</strong></span><br />
<br />
The first "bottleneck" where you will have problems sending and receiving information will be your modem. Your modem sends approximately 3400 bytes per second, your game will often update the screen to show you new visual information 30 times per second, or more.<br />
<br />
 However, it is not necessary to update the network connection this quickly, as real movements and actions do not change as quickly as the eye can detect most often. Normally you will not need to have the network connection updated more than 10 times per second, leaving approximately 340 bytes per update in an ideal environment.<br />
<br />
 To understand exactly what 340 bytes per update means, you need to understand what kind of information needs to be updated in the game and how many bytes each one of those pieces of information will take.<br />
<br />
 Say we take a game like Quake, where you are able to turn in different directions, move in different directions, jump and shoot. Lets say we take just this information and try to update it and send it back and forth between the players. I won't bore anyone with more lessons on how computers operate at a low level, so you're just going to have to trust me on the math stuff unless you want to learn about it more or you already know it.<br />
<br />
 First we will start by determining what direction the player is looking, so that we can tell the other player's computer how to draw which direction your player is facing.<br />
<br />
 If we have less than 256 directions the unit could be facing, then we can fit it into 1 byte. Most likely the game allows for more than this, but we can fudge it so that it looks correct enough on the other persons display so that this will be fine. If we store the direction a player could be looking up or down we will need an additional byte. This means we have 2 bytes that will need to be sent every update for the characters facing information.<br />
<br />
 Now we have the direction and speed/distance you are moving. To make this easier we can just send what game developers call a "delta", which in math they use to mean a change, so we will just send the changes in coordinates from the last position. To update the unit's position in the 3 axis's X , Y and Z we will need 2 bytes each to store a change of up to 64,000 unit positions in any axis. If we can shrink this movement down to be limited to a 256 unit change we can reduce the bytes needed from 6 to 3, but for arguments sake we will say we cant, so we need 6 bytes bringing the current total to 8 bytes.<br />
<br />
 To figure out when the unit jumps a lot is left up to the user, as they may let go at any time, so we will just turn on a flag that says it unit is jumping and at what height position they are currently at. If the user lets go before we update again, it will be less of a mistake then if we only update where the unit's current height is, as you can only jump so high. So we add on another two bytes for the time the user pressed jump, which brings us to the total of 10.<br />
<br />
 We'll use another byte to add on the time a weapon was fired and we also have to pass on what kind of gun we are using so that the other computer knows what type of projectile to attack with which will take 3 bytes, bringing us to 13 bytes.<br />
<br />
 Assuming that there can be 8 players at any time in a multiplayer game, we need to be able to send 104 bytes per update to give just this minimal information for each of their actions. There are a few more areas that need to be covered for players as well as some server synchronization items, but we will leave those out for this discussion.<br />
<br />
 These 104 bytes needs to be sent over the Internet through a protocol, and the one most games use it called UDP, which takes up 8 bytes to address information about the packet and where it is coming from and going. So to travel over the Internet our packet would need to be a grand total of 112 bytes, which is well under the 340 byte per update limit.<br />
<br />
 Unfortunately modems rarely get their full speed over the Internet, and packets are often lost. If we sent more information it might not matter if a packet was lost, as we may be able to send all the information needed each time. This is usually not done just because the idea is that if you have a bad Internet connection, you may not be able to play smoothly anyway, but if you have a good connection you will most likely have a better chance of fast updates by sending less information and having the risk of having to resend the packets that are lost.<br />
<br />
<span style='font-size: 18px;'><strong class='bbc'>The Home of Lag: The Internet</strong></span><br />
<br />
There are many things that can happen to your packet when it enters the Internet: it can collide with another packet and need to be resent, it can get lost in the shuffle of routers if a normal connection is down or it can be delayed on a busy network or a number of them.<br />
<br />
 Since going into full detail on the life of a packet would require a lot of background and messy details, Ill skip to the real basics.<br />
<br />
 Firstly, the more network devices your packet has to travel through, the longer it will take, and the more chance it will collide with another packet and never reach its destination. In network terms, we call these hops. A packet will hop from your ISP's computer which you are connected to, to your ISP's router, then to your ISP's feed's router, then it will hop along the feed's backbone's routers a couple of times and land on the destination computer's ISP's router, then ISP's computer, then your destination computer.<br />
<br />
 That's a lot of hopping around, and a lot of chances that you will get a collision. Physical location usually means you have less hops to go once you leave your ISP to the destination ISP, but this isn't always so. You can actually track the amount of hops from your machine to a destination with a tool called "trace route" which will also give you lag times for each hop along the way, so you can find the culprit slowing down your connection. Unfortunately, there usually isn't much you can do about this, unless you find out its your ISP, then you can switch to another.<br />
<br />
 Average ping times to different sites with a good connection (T-1 or greater) can be about 11-20 milliseconds (ms), average pings to slower sites range more along 70-100 ms, slower pings can be up to 300 ms regularly and can get EXTREMELY bad where it can take several seconds to reach. Packets however don't live this long, they can only bounce around so many times before they are considered obsolete, so the information is better to just be resent.<br />
<br />
 Taking 300 ms as a time you may actually get often enough on a dial-in modem, you can see that you have a lag time of 1/3 of a second between when you send your information, and when you receive an update from the other player which is a good deal less than the 10 updates a second we said were theoretically possible above. This means that what he did 10 frames ago (on the 30 frames/second model) , you are just seeing now, which means you are very out of sync with each other. If you have a lag of 100 ms instead you will only have a 1/9 of a second or seeing what happened 3 frames ago on your system. This is an improvement by far, but if the game relied solely on this information your opponent would still seem to move in a choppy fashion and seem slow to respond. So what are the solutions?<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Smoothness via Duct Tape</strong></span><br />
<br />
Since you cant make the Internet go any faster, and not everyone can have high speed connections or be in the same room or building with each other when they play game developers have had to come up with alternative solutions to how to make multiplayer games seem smooth.<br />
<br />
 What is commonly done is called interpolating the figures, this is just making an educated guess. If the player is running forward now, then player will more than likely be running forward still on the next update, so until we hear from them, we will assume that they are running forward and move them on the screen this way.<br />
<br />
 This is how you end up with false kills and things that should have been hits, but weren't, because the system was showing you something but in fact, the other player wasn't really there, you just hadn't gotten the update yet.<br />
<br />
 Other factors that are involved in this, is how the game determines what is happening and what isn't. So far I have describe the networking in what is called a client to client game. The individual computers just share information about what is happening with each other. This doesn't work very well when you start adding more people though, as you end up waiting for information on everyone, which is taking more of your valuable modem bytes per second.<br />
<br />
 So another model is what is called a client-server mode. One machine acts as the server, and all updates are sent to it. Then it sends updates back to all the clients and tells them what other clients are doing. Depending on how the game developers made the software, the server may be the machine that determines whether something is a kill or not, or it may all be individually handled on the client machines and the server just passes on the information.<br />
<br />
 How this is all accomplished could take up a whole article in itself, so let's wrap this up....<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>It isn't as easy as it sounds</strong></span><br />
<br />
Most likely you didn't read all of this and decide it was easy, but unfortunately, it's even harder than I described it. Normally games are sending much more information or stats then I originally provided for, and sometimes they have to provide information for thirty two, or more players. That means you can send less information with every update if you expect to do it as often or update less or some combination in between.<br />
<br />
 There is a LOT of tweaking by adjusting small amounts of "how much to send" and "how often to send it", and it just can't be done off the top of your head. This is an extremely hard process to design and implement and it becomes all the harder because the major decision maker on whether the information will get there or not is totally out of the designers hands: the Internet.<br />
<br />
 Hopefully this cleared up some of the questions you had about what lag is, why it occurs and what is being done to try to work around it. Developers are really trying to make the best multiplayer experiences they can and it takes a lot of individual tuning for each game to do it properly and a lot of testing to get it right.<br />
<br />
<a href='mailto:ghowland@lupinegames.com' title='E-mail Link' class='bbc_email'>-Geoff Howland</a><br />
<a href='http://www.lupinegames.com/' class='bbc_url' title='External link' rel='nofollow external'>Lupine Games</a>]]></description>
		<pubDate>Tue, 14 Sep 1999 13:08:59 +0000</pubDate>
		<guid isPermaLink="false">a51c896c9cb81ecb5a199d51ac9fc3c5</guid>
	</item>
	<item>
		<title>The Internet, A Summary Introduction to TCP/IP,...</title>
		<link>http://www.gamedev.net/page/resources/_/technical/multiplayer-and-network-programming/the-internet-a-summary-introduction-to-tcpip-r711</link>
		<description><![CDATA[CONTENTS <strong class='bbc'><br />
<br />
Relevant Background on the Internet</strong><br />
<br />
 <strong class='bbc'>The TCP/IP Suite</strong><br />
<blockquote>What's a protocol and how do I use it?<br />
How are protocols maintained by the Global Internet?<br />
The TCP Protocol<br />
The UDP Protocol<br />
The IP Protocol <blockquote>IP Addresses<br />
The Domain Name System<br />
The ICMP Protocol<br />
The GGP Protocol<br />
The ARP and RARP Protocols</blockquote></blockquote><strong class='bbc'>Physical Protocols and Why we Don't Care</strong> <strong class='bbc'><br />
<br />
TCP/IP Programming</strong><br />
<blockquote>Win32 TCP/IP Support: WinSock<blockquote>Initializing the WinSock Library<br />
Creating Sockets<br />
Binding and Connecting<br />
Addressing and Name Service Support<br />
Network and Host Byte-order<br />
Sending and Receiving Data<br />
How to get your sockets to listen()<br />
Blockage and Synchronicity<br />
Errors in WinSock<br />
Cleaning up after yourself<br />
What I didn't cover</blockquote></blockquote><strong class='bbc'>Coda</strong> <strong class='bbc'><br />
<br />
Disclaimers</strong><br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Relevant Background on the Internet</strong></span><br />
<br />
The history of the Internet is vast and vibrant, filled with exciting people, stunning breakthroughs and unbelievable events, intruige, imagination, and all of that great sort of thing. Tens of thousands of pages have been written on its development alone. Obviously, then, it is not my intention to sit and talk to you about the history of this marvel of technology, of this manefestation of our science. I'm just going to present you with enough trinkets to realize that all (well, most, anyway) of its arcane complexity is absolutely vital.<br />
<br />
 The United States first suggested a communications Internet as a tactical advantage in 1962. Communism was on the rise, tensions were high, and the increasing threat of nuclear warfare was widely perceived. The United States Air Force challenged a select group of R&D people to come up with a network that could withstand a nuclear attack. The network that they envisioned was called a Distributed Communications Network, or a "decentralized" network, which was a theretofore unheard of concept. The idea was simple. If one node was destroyed, the capacity to exchange data had to remain in place. Paul Baran, with the RAND corporation at the time, conceptualized such a network in full detail (FULL detail). Unfortunately, due to a rather breaucratic review of Baran's research, nothing happened until 1969. Finally the time was ripe: Research merged with funding and this with renewed government interest (on behalf of DARPA, Defense Advanced Research Projects Agency), resulting in the birth of the ARPANET.<br />
<br />
 The ARAPNET gradually grew and expanded in amazing ways not very important to us. It started with four hosts. Four years later, it had 40. With the invention of e-mail in '72, a new surge of data relied on the network. Incredible though it may seem, most of the data sent and received via ARPANET was e-mail at the time. Now keep in mind, in the mid-70's, TCP/IP also came along and fundamentally redefined the way that communications over the network were carried out. By the first few years of the 80's, there were hundreds of hosts. In 1988, there were over 51,000. In 1990, there were well, well over 300,000 hosts. Another milestone in '90: The government gave control of the network to the National Science Foundation (NSF), who subsequently released it to the public domain due to excessive backbone operating and upkeeping costs. Commercial business promptly moved in for the kill.<br />
<br />
 Well, to make a long story short, a group at the U of Minnesota came up with Gopher, an independent European innovator conceived developed HTML, along with the web browser, and the rest is history. Public recognition of the Internet spread like wildfire. Don't ask me who counts, but the size of the Internet has increased by over 25,000% from 1969 to the present.<br />
<br />
 To clear up a few misconceptions: The Internet is not one network. It is a set of networks linked by gateways. The term "internet" means any combination of networks in general: In fact, to avoid confusion with "The Internet", as we call it, corporations denote their internal internets "intranets." Gateways are devices that connect networks in an internet, as was just implied. Routers are devices that decide which way data is going to travel over a network to get from point A to point B. Incidentally, a subnet is a network in an internet. Go figure.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>The TCP/IP Suite</strong></span><br />
<br />
"So where does TCP/IP come in," you wonder? To set the record straight, TCP (Transmission Control Protocol) and IP (Internet [general, not specific to the Internet] Protocol) are just two internet data transfer protocols. IP is the basis of all Internet communications. TCP is the underlying protocol that makes communications on the global Internet reliable. The TCP/IP suite, on the other hand, is a group which contains most of the essential internet-related protocols that you'll ever worry about. It is comprised of protocols in two basic layers. The first and foremost layer in the suite is the Network Layer, which contains the basic, underlying protocols that make Internet communications possible. The layer above this is the Application Layer, which contains high-level protocols (those with which the user must interact) designed to transmit commands specific to a certain task.<br />
<br />
 <strong class='bbc'>What's a protocol and how do I use it?</strong><br />
<br />
 Loosely stated, a protocol is an established format for data transactions over a network. Network-level protocols in the TCP/IP family, namely DP, TCP, ICMP, IP, ARP, and RARP (those are the ones which you will ever even remotely have a chance of using as a game developer, in that order) are almost always implemented by the operating system, which is a blessing beyond all other blessings.<br />
<br />
 This means that when we're concerned with developing applications that use the TCP/IP protocol suite for Internet communications, we usually interface to its Network level protocols by calling upon the operating system or operating system extension API functions. Attempting to implement the entire Network-level TCP/IP suite is overkill, especially since it has already been done for just about every platform (including DOS) that is currently in widespread use. If you ever did decide to implement it, the information to do so is freely available...but it's a lot of work, and might I add a lot of unnecessary work.<br />
<br />
 <strong class='bbc'>How are protocols maintained by the Global Internet?</strong><br />
<br />
 Protocols are only a small part of a large process of Internet standardization. Standardization and modernization is an entirely open, ongoing effort, carried out by way of memos called Requests for Comments (RFCs). When a proposed standard or effort that requires the attention of the entire professional Internet community is to be addressed, usually the ideas involved are published in the form of an RFC. Note that RFCs are a form of technical Internet intercommunication, and are usually not intended as documentation; generally, they either express respected and developed research that may or may not improve and update the network, or refine older standards. They are numbered in order of publication, starting with RFC 1, which was, incidentally enough, put out back in 1969. At the time of this writing, they approach 2500 in number [that should keep this "current" for long enough...]<br />
<br />
 In order to facilitate better understanding of the contents of Requests for Comments, they are classified into various groups. Informational RFCs are, obviously, informational, and Exprerimental RFCs are experimental (surprise surprise).<br />
<br />
 Standards Track RFCs are RFCs in various stages of standardization, ranging from Proposed Standard, to Draft Standard, to Internet Standard. In order to become a standard, an RFC must move along the full run of the standards "track". The "track" is a set of rigorous phases of scrutiny, testing, review, and refinement that any standard on the Internet must go through before it can really be called "standard." The Internet Standards Track Reference is a document containing the state of standardization of various standards.<br />
<br />
 Historic and Obsoleted RFCs are somewhat different, at least I like to think so; the historic RFC is one maintained for its historical interest, as if it ever had a practical one. Among these are included memos from the 60's or 70's discussing network meetings. Obsoleted RFCs contain information which has been outdated by newer developments. Usually, where an obsolete RFC is listed, the RFC which has obsoleted it is listed alongside it.<br />
<br />
 Incidentally, all RFCs of which I am aware are distributed on an unlimited basis, which means that you can pretty much find them anywhere. They're available freely. However, since there are absolutely no distribution restrictions whatsoever, you also have the right to rip people off for them (but only an ignoramus would buy what he can get in the same condition for free!) A good RFC archive is at <a href='http://info.internet.isi.edu/1s/in-notes/rfc/files' class='bbc_url' title='External link' rel='nofollow external'>http://info.internet...notes/rfc/files</a>. You might want to refer to the RFCs for in-depth discussions on unusual standards. The information is all there.<br />
<br />
 By the way, I don't believe I mentioned it...RFC 2324 is my present favorite.<br />
<br />
 <strong class='bbc'>The TCP Protocol</strong><br />
<br />
 TCP is crucial in reliable Internet communications. It does quite a bit. Foremost, it monitors what gets through to a remote host and what does not, and retransmits anything that doesn't. It also must perform other assorted tasks. Say that a packet is too large to fit into one IP packet: TCP will split it up into smaller packets. The TCP protocol uses the IP protocol to actually transmit data. Basically, the goal of TCP is to make sure that data gets from a place to another place in 100% intact condition. This "perfectness" is absolutely essential for the Internet to be worth-while at all: If one op-code in a binary is misplaced, the whole thing falls appart. One misplaced digit in a military data file could spell disaster.<br />
<br />
 Multiple conversations can be going on between two machines at the same time between more than one process on these machines. The ability to handle this scenario is called multiplexing, and TCP provides a set of "ports", uniquely identified via "port numbers" on a given host, through which various data are sent and received, in order to pull it off. There are assigned TCP port numbers for various application protocols. Beyond this, a user process may independently select ports for a conversation. This port information, together with the information that the IP protocol uses to identify an individual machine on the Internet, forms what is called a TCP socket, or alternatively, just a socket. All sockets are completely unique on the Internet, that is, a socket is on one and only one host and one and only one port on that host.<br />
<br />
 To use TCP, you must connect a socket on the local machine to a socket on the remote machine. This occurs in three steps: First, TCP sends over a connect message from the local socket. The remote machine acknowledges, the remote socket sending a response to the local socket. Then the socket on the local host again acknowledges. A TCP connection is then said to have been opened. This process of negotiating a connection is called handshaking. Specifically, the handshaking method that TCP uses is called a three-way handshake. Once a connection has been formed, TCP can transmit data. TCP communication is bidirectional, that is, both parties in a connection can send and receive data. A single TCP socket can participate in more than one connection at a time, and can have more than one remote socket connected to it. Because of the significance of establishing connections in TCP, it is refered to as a connection-oriented protocol.<br />
<br />
 TCP takes basic data that needs to be transfered and wraps a header around it. The header is complicated, but then again, so is TCP. Here's generally what it looks like:<br />
<br />
<p class='bbc_center'><strong class='bbc'>  TCP Header</strong><br />
</p><br />
<center><table border="3" cellpadding="0" cellspacing="0" width="50%"><tbody><tr><th><strong class='bbc'>Item</strong></th><td class="tblhdr"><strong class='bbc'>Size (bits)</strong></td></tr><tr><td>Source Port</td><td>16</td></tr><tr><td>Destination</td><td>16</td></tr><tr><td>Sequence #</td><td>32</td></tr><tr><td>Ack. #</td><td>32</td></tr><tr><td>Data Offset</td><td>4</td></tr><tr><td>[Reserved]</td><td>6</td></tr><tr><td>Control Bits</td><td>6</td></tr><tr><td>Window</td><td>16</td></tr><tr><td>Checksum</td><td>16</td></tr><tr><td>Urgent Pointer</td><td>16</td></tr><tr><td>Options</td><td>Not fixed (multiple of 8)</td></tr><tr><td>Padding</td><td>Optional, only used if packet doesn't end on 32-bit boundary</td></tr></tbody></table></center>In general, you can expect to see TCP headers getting to about 22 octets (an octet is an 8-bit byte) on average. Despite the meager sound of it, this is a quite large and cumbersome header size. It is for this reason, the huge header, coupled with the reason that TCP is just fundamentally "the wrong thing" for a game, that TCP is rarely used in games. What I mean by "the wrong thing" is explained best by way of example...if you shoot someone in a deathmatch and a TCP packet is sent to indicate it, what's the point of retransmitting it ten times until it's in perfect order? The fellow you shot is already cold by the time it finally gets through.<br />
<br />
<strong class='bbc'> The UDP Protocol</strong><br />
<br />
 The User Datagram Protocol is another common protocol in the TCP/IP suite. The protocol was designed to provide an ad-hoc direct transportation mechanism for information without oversized TCP headers and the complexity associated with them. However, what UDP gains in elegance, it loses in reliability. Unlike TCP, UDP does not implement "quality assurance" with regard to the data that it transmits, in any way, shape, or form. UDP packets may be duplicated, out of order, or not received at all. On the other hand, UDP does cut back on the mammoth TCP header overhead, which adds up over time, especially if your TCP packets are so large and ill-designed as to consistently be split up.<br />
<br />
 The aspect of UDP that stems largely from its intended design as a generic, low-key data transport mechanism is that it is entirely connectionless. That is to say, one does not have to establish a connection to a remote host in order to transmit packets to it or receive packets from it under UDP. Packets are simply transmitted over the network. Although it may seem odd, this model is basically what allows UDP to remain as compact as it is.<br />
<br />
 The User Datagram Protocol tacks the following header onto the top of the data:<br />
<br />
<p class='bbc_center'><strong class='bbc'>  UDP Header</strong><br />
</p><br />
<center><table border="3" cellpadding="0" cellspacing="0" width="50%"><tbody><tr><td class="tblhdr"><strong class='bbc'>Item</strong></td><td class="tblhdr"><strong class='bbc'>Size (bits)</strong></td></tr><tr><td>Source Port</td><td>16</td></tr><tr><td>Destination</td><td>16</td></tr><tr><td>Length</td><td>16</td></tr><tr><td>Checksum</td><td>16</td></tr></tbody></table></center><br />
 8 octets as opposed to 22+...it's quite a simplification indeed. Always bear in mind, however, that UDP is unreliable, and you never know how unreliable. Design carefully.<br />
<br />
 It should also be noted that in the context of UDP, port numbers have less significance on the Network level than do TCP port numbers. Rather, UDP port numbers are more significant towards an individual application. There are, however, established UDP protocol port numbers, as there are established TCP port numbers, for various application level protocols. Rule of thumb: Always, always check both the assigned port numbers and the commonly used port numbers before you attempt to use a port for personalized data transport, and even then only use a port towards the top of the accepted "user" port list. You will usually find links to assigned port information on the web alongside RFC listings.<br />
<br />
<strong class='bbc'> The IP Protocol</strong><br />
<br />
 IP is relied upon by just about everything. It's the cornerstone of all Internet communications. IP also is rather conceptually simple. It has exactly one goal and one dream in life, and that's to get packets from a source address to a destination address. IP transmits data in the form of packets called datagrams. Datagrams are composed of a header, which is 20 octets large, and a data area. Although IP doesn't give a rip about what's inside the data area, usually the data area will be composed of a TCP or UDP header followed by raw data when IP sees it. Thus, the IP header is just plopped on top of any other headers that might be present over the data. This is how Internet communications works in general; layers of protocols on the local host wrap their headers around the data and it is transmitted, then various layers peal the headers away from the data as it is processed by the remote host, and eventually a specific application gets the data.<br />
<br />
<p class='bbc_center'><strong class='bbc'>  IP Header<br />
</strong></p><br />
<center><table border="3" cellpadding="0" cellspacing="0" width="50%"><tbody><tr><td class="tblhdr"><strong class='bbc'>Item</strong></td><td class="tblhdr"><strong class='bbc'>Size (bits)</strong></td></tr><tr><td>Version Number</td><td>4</td></tr><tr><td>Header Length</td><td>4</td></tr><tr><td>Type of Service</td><td>8</td></tr><tr><td>Packet Length</td><td>16</td></tr><tr><td>Packet ID</td><td>16</td></tr><tr><td>Fragmentation</td><td>16</td></tr><tr><td>Time to Live</td><td>8</td></tr><tr><td>Protocol</td><td>8</td></tr><tr><td>Header Checksum</td><td>16</td></tr><tr><td>Source Address</td><td>32</td></tr><tr><td>Destination Address</td><td>32</td></tr></tbody></table></center><br />
<strong class='bbc'>IP Addresses</strong><br />
<br />
 IP addresses are the standard means of identifying Internet hosts. An IP address is a 32-bit integer. By convention, in written form, each octet of an IP address is written in base-10, separated by a ., big endian. Consider that you are on a little-endian machine (the least significant octet of a word trails in memory). When an IP address, or any data for that matter, is received from a big-endian remote host, you must convert it to little-endian before it is significant to the machine. Big-endian notation is always used to represent IP addresses. For this reason, big-endian is said to be the network byte order. TCP/IP implementations will usually provide functions to convert from the network byte order to the local host's byte order, and should, if competent, process the information in the header correctly regardless of byte order.<br />
<br />
 For instance, the IP address 127.0.0.1 is the "local loop-back" address by convention for the Linux TCP/IP implementations, which means that data sent to this address will be looped back to you. (Just an interesting tid-bit.)<br />
<br />
 In order to facilitate networks of different sizes, IP addresses are divided into a network address and a host address. The network address identifies the network in an internet to which a datagram is being sent, and the host address identifies the specific host on that network to give the datagram to. The way in which these portions of the address are allocated determines the "class" of an IP address. IP addresses are organized into four distinct classes.<br />
<br />
<p class='bbc_center'><strong class='bbc'>  IP Address Classes<br />
</strong></p><br />
<center><table border="3" cellpadding="0" cellspacing="0" width="90%"><tbody><tr valign="top"><td class="tblhdr"><strong class='bbc'>Class</strong></td><td class="tblhdr"><strong class='bbc'>Number of Network Addresses</strong></td><td class="tblhdr"><strong class='bbc'>Number of Host Addresses</strong></td><td class="tblhdr"><strong class='bbc'>Generalization</strong></td></tr><tr valign="top"><td>A</td><td>126</td><td>16,177,214</td><td>One of few mammoth networks</td></tr><tr valign="top"><td>B</td><td>16,383</td><td>65,534</td><td>One of many larger networks</td></tr><tr valign="top"><td>C</td><td>2,097,162</td><td>254</td><td>One of a lot of small networks</td></tr><tr valign="top"><td>Ext.</td><td>N/A</td><td>Indefinite</td><td>N/A</td></tr></tbody></table></center><br />
We never really need to worry about these classes, but if you're curious, the class of an IP address can be physically determined in two ways: First off, if there's a pink flamingo anywhere on its front lawn and it drives a sport utility vehicle, then it is probably of a higher class. The other common approach is to look at the range of its most significant octet. A MSO from 0-127 indicates class A, from 128-191 class B, from 192 to 223 class C, and from 224-255 an extension address.<br />
<br />
 The extended IP address class, described in RFC 1112, is used for multicasting (sending a single packet to more than one host at a time), and we will not concern ourselves with it.<br />
<br />
 One would like to think that this is it. However, on a lower level, there's still the concern of how IP gets a packet to a given IP address. This process is called routing, and can become moderately complicated. Fortunately enough, for our purposes, it's simple, because we don't have to implement it.<br />
<br />
<strong class='bbc'> The Domain Name System</strong><br />
<br />
 IP addresses can get a bit cryptic, and there are certainly a lot of them, as you have seen (to be specific, there are 4,294,967,296 possible IP addresses--but this will one day be not-enough! Remember, there are already about six billion humans on Earth.) While it may be possible in class C networks and smaller internets to simply maintain a hosts file that contains the name of every host and an IP to go along with it, this is not even CLOSE to practical for the 10,000,000+ host Global Internet of today. A file containing the complete database for all IP addresses would be about (conservatively) 94,489,280,512 bytes in size: 90,112 megabytes, 88 gigabytes. Few hosts could sustain such a database, and fewer still could search it. This would limit and centralize network capacity, which would be a big no-no based on the decentralized Internet philosophy. Moreover, it would be a real pain to append and mend these records. Therefore, as a solution to the problems associated with maintaining IP databases, the Domain Name System (DNS) was developed.<br />
<br />
 DNS is a hierarchal IP address lookup system that uses text strings to classify IP addresses in increasing precision. In other words, it uses a tree system to decentralize the process of looking up hosts. Host addresses under the DNS take the form host.subdomain.domain. The domain at the highest level of the tree is called the root domain. The root domain contains all of the top level domains, among the most common of which are gov, edu, com, mil, and org, and ISO two-letter country abbreviations.<br />
<br />
 A name server is a server program that maintains information about the domain structure and how it relates to IP addresses. Name servers do not contain information for all parts of the domain name hierarchy; rather, they contain pointers to other name servers than know about parts of the domain name hierarchy that they do not. Similarly, if a name server knows about the structure of a particular part of the domain name hierarchy, other servers may be linked to it. Other programs called resolvers then access name servers to map domain names to IP addresses, and vise-versa. In this manner, host address information can be maintained without centralizing it, and in such, the network is able to sustain itself without relying too much on any particular host. Most ISPs maintain (a) name server(s).<br />
<br />
 RFCs 882, 1043, and 1035 provide a decent higher-level introduction to DNS. This is recommended reading for anyone curious as to how it actually works. Fortunately once again, we get DNS as a freebie with civilized operating systems.<br />
<br />
<strong class='bbc'> The ICMP Protocol</strong><br />
<br />
 An integral part of IP is ICMP. It is difficult to explain the role of the the Internet Control Message Protocol from an application programming standpoint, because it is really a low-level sort of thing that's a direct part of IP. However, to state it simply, ICMP is used by gateways (devices which connect the various networks of an internet) to communicate with hosts or vise-versa. Its application is in reporting or querying errors in the data transaction process. Because of the nature of ICMP, I will not discuss its specifics. The only real application-level use for ICMP that I have ever run across is the ping network utility, which sends ICMP packets to test whether or not a remote host is accessible and measure the transaction time between that host and another (this is sometimes called the "ping time"). While this might have applications in a game, excessive pinging can clog things up, something which we want to avoid doing in a multiplayer simulation. (In fact, there is a common [but stupid, primarily because you're basically giving away your address to the person you're cracking, and it's illegal] denial-of-service attack called flood pinging which is rather similar...)<br />
<br />
<strong class='bbc'> The GGP Protocol</strong><br />
<br />
 The Gateway to Gateway Protocol is another protocol that lives with IP. It is designed for communication about routing between two gateways. Suffice it to say that it does not concern us at all, because obviously we are not managing IP-level transactions.<br />
<br />
<strong class='bbc'> The ARP and RARP Protocols</strong><br />
<br />
 The Address Resolution Protocol and Reverse Address Resolution Protocol are designed to take Internet addresses and convert them to specific local hardware addresses. This task is obviously way beyond the scope of what we need to consider for application-level TCP/IP programming.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Physical Protocols and Why we Don't Care</strong></span><br />
<br />
Physical protocols are protocols which manage actually moving a piece of data across an internet. IP deals with working data through routers on a "high level", but it does absolutely nothing about actually getting data from one router to the next. This is where physical protocols come into play: Once a piece of data has reached a router via IP and the data needs to move on, the services of a physical protocol are called upon to do this moving on. The router slops another header on top of the IP header (and sometimes adds a footer to the end) and ships the packet away. When the destination router receives it, it peals the header off, and appends another one which will be needed to get it to the next router, which repeats the process, ad yada yada yada. The only time that we even remotely care about physical protocols is when we're talking about the last leg in the data transaction process for the typical end-user/gamer: From the ISP to the modem.<br />
<br />
 The Point to Point Protocol (PPP) is the most commonly used physical protocol for transferring such data between modems. Let's say that a packet destined for a dial-up user has been sent from a remote host and has finally been routed to the appropriate place on the ISP. For the ISP to actually route the packet to the user's machine, a physical protocol needs to be called upon. This is probably going to be PPP. So the ISP attaches the PPP header and footer and ships the packet over to the user via the established PPP modem connection, it is received by the user's modem, and picked up by whatever local low-level telecommunications support is running. The PPP header is then pealed off by the local host's PPP support, and the IP header is seen. The IP header is processed, pealed off, and the TCP or UDP header is seen. The local host uses the information in the TCP or UDP header to direct the packet to the correct port on the local host, then peals the headers away, leaving just the data to be processed by an application running on that port.<br />
<br />
 We care about that process for three reasons: First of all, it's interesting, second of all, it's easy to explain, and finally, because it sounds impressive. Other than that, we needn't concern ourselves with physical protocols. They are at a way lower level than we will ever touch as practical game programmers. The only time when we will even remotely care about PPP is when we're optimizing and investigating where overhead comes from.<br />
<br />
 If we were actually implementing TCP/IP support for a new platform, then yes, we'd care about physical protocols quite a bit, or if we were going into overkill mode and doing it all ourselves, we'd care about it. But as it is, if we've got support for TCP/IP on our target platform, then it's almost a given that there will be atomic support for PPP or SLIP or an equivalent physical protocol in place and active. My other articles on multiplayer technologies for Game Programming MegaSite have been primarily extremely low-level, concerned mainly with programming for the modem: If I were to continue that trend, I would go into the specifics of PPP and the hell of implementing it and all the layers of complexity above it. Unfortunately, I don't think that perplexed.com has a big enough disk for that, and I'd be wasting your time. So, we don't really care.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>TCP/IP Programming</strong></span><br />
<br />
When we speak of developing TCP/IP applications, we rely on four layers of functionality:<br />
 <ul class='bbcol decimal'><li>An application protocol specific to what we're trying to do (SMTP, for instance)</li><li>TCP or UDP to oversee data transaction</li><li>IP, to actually transmit data packets to a given destination</li><li>Physical protocols like PPP to make data transfer happen.</li></ul> Most of these layers are supported directly by the operating system. Our task usually comes into play when it boils down to implementing or supporting a specific application-level protocol, whether standard (as would be the case with a common system utility like finger or sendmail) or propietary (as would be the case with Quake).<br />
<br />
 On any civilized platform, layers 2-4 will be provided for you. If you have to implement any of layers 2-4, you're not dealing with a civilized platform and you're probably wasting your time. Those operating systems which support development of TCP/IP applications with components that are part of the main operating system API are said to have "native" Internet support. Examples of such operating systems are 4.2BSD, Windows NT, and Windows 95. Operating systems which require the use of a propietary API for applications which utilize TCP/IP are said to have no native support for TCP/IP. Examples of these operating systems include Windows 3.11 and DOS.<br />
<br />
<strong class='bbc'> Win32 TCP/IP Support: WinSock</strong><br />
<br />
 Win32 supports TCP/IP via WinSock, a port of the popular Berkley Sockets technology. Socket, of course, refers to a TCP or UDP socket in a connection. WinSock suffered from some slight loss of elegance when it was ported from BSD, namely because of fundamental differences between BSD and Win32. The most visible change for experienced Berkley Sockets developers would be that you have to (as in, must) initialize and de-initialize the WinSock library. On a deeper, uglier level, files and sockets were--before 2.0--completely different ball-parks in WinSock, because of course BSD != Windows 95. A recent effort in 2.0 has endeavored to cover the tracks of the Win32 platform by making this situation ad-hocable. (Thank you, come again.) WinSock, like Berkley Sockets, is purely procedural.<br />
<br />
 What you should not use WinSock for is implementation of extremely common application-level TCP/IP protocols, if you can at all avoid it or if you don't need excessive control. Win32 already provides rather sufficient application-protocol-level Internet support for mail protocols, HTTP, FTP, and gopher. For most purposes, this support is enough. Low-level implementation of these protocols would be tremendously educational, but otherwise, a waste of time (for the most part; although you might consider writing an HTTP or FTP server for Windows 95).<br />
<br />
 On a personal note, I think WinSock is a stupid name, even if it is also a bad pun. I would've preferred that it be called "Lose Underwear." People can identify with this more. Frequently, I have observed that people lose underwear, whereas they very seldom win socks, unless they're playing a game of five card stud without a full deck or they're the 72nd shopper at K-Mart. That's just me, though.<br />
<br />
<strong class='bbc'> Initializing the WinSock Library</strong><br />
<br />
 To initialize WinSock, you call WSAStartup(). The first parameter of WSAStartup() gives the highest version of WinSock that your program can use. The library then uses a decision table based on the version given and the versions supported to decide whether or not it can effectively support your application. Parameter 1, the version requested, is a WORD. WinSock versions that you can request include 1.0, 1.1, and 2.0 (at present). Use the MAKEWORD macro to form the version for the first parameter, as follows: MAKEWORD(2,0) = version 2.0. For simplicity and maximal compatibility, it's a good idea to request the earliest version of WinSock that supports what you need to do.<br />
<br />
 The second parameter of WSAStartup() is a pointer to a WSADATA struct to get the specific initialization information. The WSADATA structure will contain information about the actual version of WinSock that you've gotten a hold of, as well as some limits that might come in handy for something and might not.<br />
<br />
 The return value of WSAStartup() is an error code. If the error code is 0, then obviously there was no error and we can proceed to use the WinSock library. The constants representing error codes usually take the form WSAEx, where x is the specific descrition of the error.<br />
<br />
 [indent]<pre class='prettyprint'>WSADATA wsaData;<br />if (WSAStartup(MAKEWORD(1, 0), &wsaData)) {<br />   ErrorMessage("Error while attempting to initialize WinSock");<br />}</pre><br />
[/indent]<strong class='bbc'> Creating Sockets</strong><br />
<br />
 To create a socket, you call either socket() (real shock, eh?) or WSASocket(). As is the case with many WinSock functions, the fancy WSA prefix functions are easily distinguished from their counterparts preserved for portability. In this tutorial, I will cover the preserved Berkley forms of the functions in WinSock for the most part. Why? Because most of them don't have "extensions" built in, and are consequentially easier to understand.<br />
<br />
 The first parameter of socket() specifies the address family that a socket will use. This is related to the way/place in which data transferred over the socket will be sent/will go. For the purpose of Internet-based TCP/IP programming, AF_INET will work. However, if you feel like having fun, check out the AF_x line of constants in winsock.h or winsock2.h. You might be surprised at the sheer number of networks that Winsock can be applied to.<br />
<br />
 The second parameter of socket() is the socket type. SOCK_STREAM will form a stream-based socket (surprise surprise) that supports bidirectional data transfer and an internally managed transfer buffer, and is generally more reliable than other socket types, such as SOCK_DGRAM. Check out the SOCK_x line of constants in winsock2.h for more of these socket types (if you have Winsock 2.0...1.0 and 1.1 support only the two mentioned above).<br />
<br />
 The third parameter of socket() is the protocol that the socket is to use. These take the form IPPROTO_x. IPPROTO_TCP, for instance, specifies the TCP protocol. IPPROTO_UDP specifies the UDP protocol. IPPROTO_IP specifies the IP protocol (right...). Once again, consult your handy header file for more information.<br />
<br />
 socket() returns a handle to the newly created socket, an integer (SOCKET is #defined as a u_int). In fancy-talk, this integer is called a socket descriptor.<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);</pre>[/indent]<strong class='bbc'> Binding and Connecting</strong><br />
<br />
 Immediately after its creation, a socket can do nothing. Before it can do anything, we must define which port number a socket is to pay attention to and which host that port is on: That is, we must actually associate our socket with a socket! To attach a socket to a port on the local machine, use the bind() function. To connect a socket to a socket on a remote host, use the connect() function.<br />
<br />
 There is a crucial distinction that needs to be made between bind() and connect(). First and foremost, as has already been stated, bind() is used to attach a socket to a specific port on the local machine, and this only before connection. If you attempt to connect() without binding a socket to a port on the local machine, connect() will bind it randomly for you. If you attempt to bind() while connected, you will be doing something very strange. The second distinction is that bind() is usually used in conjunction with listen(), which listens for a connection on a given socket. This does not mean that bind() has to be used in this manner. Seldom does one have to bind to a specific local port when performing a transaction with a remote machine. The similarity between bind() and connect() would be that they have effectively the same parameter list with the middle parameter replaced with the local host's address in bind().<br />
<br />
 The first parameter of connect()/bind() is a socket descriptor. The second parameter is a pointer to a sockaddr struct. This parameter indicates what the socket is to be bound to/connect to, i.e., what machine we're dealing with. This is what a sockaddr looks like:<br />
<br />
 [indent]<pre class='prettyprint'>struct sockaddr {<br />    	u_short sa_family;<br />    	char sa_data&#91;14&#93;;<br />};</pre><br />
[/indent] sa_family is yet another instance of the family things that we've been seeing; the AF_x line of constants can be used to specify this. This family will more likely than not be the same one used in the creation of the socket. In fact, if it's not, give me a ring, because that would be extremely unusual. sa_data contains the address of the remote machine.<br />
<br />
 One might ask what char sa_data[14] really means, or indeed, what this whole structure really means; that is, how the address is really formatted. In TCP/IP networks, the above structure can be rewritten like this:<br />
<br />
 [indent]<pre class='prettyprint'>struct sockaddr_in {<br />   	short sin_family;<br />   	u_short sin_port;<br />   	struct in_addr sin_addr;<br />   	char sin_zero&#91;8&#93;;<br />};</pre><br />
[/indent] (note short instead of u_short; this, I can only assume, is an error in the published WinSock documentation, upon which I have based these structure listings in order to avoid unintentionally introducing any further errata.)<br />
<br />
 For the overly curious, in_addr looks like this:<br />
<br />
 [indent]<pre class='prettyprint'>struct in_addr {<br />            	union {<br />                    	struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;<br />                    	struct { u_short s_w1,s_w2; } S_un_w;<br />                    	u_long S_addr;<br />            	} S_un;<br />};</pre>[/indent] And now you want to know why you care. Well, if you'll think back to our discussion on how IP datagrams are routed from one place to another, you'll recall the concept of an Internet address that uniquely identifies a host on a network. sockaddr_in specifies an address for a unique port on a unique host. in_addr is the actual Internet address of that host. You will note four bytes, referenced in the union through chars, shorts, and longs, just as I promised back in the IP discussion (four octets). But we don't need to worry about things on this level. That's just how it fits together.<br />
<br />
 The third and final parameter of bind()/connect() is the size of the address structure given as the second parameter. This is most commonly specified using the sizeof keyword in conjunction with the actual address structure. So, for instance:<br />
<br />
 [indent]<pre class='prettyprint'>struct sockaddr_in addr;<br /><br />...<br /><br />SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);<br /><br />//assume that we fill addr somewhere in here<br /><br />...<br /><br />connect(s, (struct sockaddr *)&addr, sizeof(addr));<br /><br />...</pre><br />
[/indent] That's the general idea.<br />
<br />
<strong class='bbc'> Addressing and Name Service Support</strong><br />
<br />
 It should be noted that sockaddr_in is a wrapper that identifies an IP address and a port on the machine identified by that IP address for practical TCP/IP development purposes. The very important question of how we know this IP address comes into play. There are really only two ways to know the IP address of a host: You can either know it outright, or look it up based upon a domain name service. WinSock encapsulates the functionality of a resolver (discussed earlier when we talked about DNS) in the gethostbyname() function. This will look up a host-name and get the IP(s) of the host or hosts associated with it if possible.<br />
<br />
 gethostbyname() has only one parameter, namely, the name of the host to get the address of. The address itself is returned in the form of a pointer to a hostent structure. WinSock will allocate this for you, so all you really need to do is get a pointer to it. Straight from the headers (well, almost), this is what hostent looks like:<br />
<br />
 [indent]<pre class='prettyprint'>struct hostent {<br />   	char FAR *h_name;<br />   	char FAR *FAR *h_aliases;<br />   	short h_addrtype;<br />   	short h_length;<br />   	char FAR* FAR* h_addr_list;<br />#define h_addr  h_addr_list&#91;0&#93;<br />};</pre><br />
[/indent] Nasty structure, really, but fortunately you won't have to worry about much of it. h_name contains the name of the host. h_aliases is an array of strings which contain aliases (pseudonyms; nick-names; alternative identities indicating one and the same thing) of the host. h_addrtype is simply the type of the addresses in the h_addr_list array. This is unnecessary for our purposes, because we're already pretty certain what they are. h_length is the length of the addresses. And finally, where our interest comes in, the h_addr_list array. This will contain the IP address(es) of the host that we have looked up. It may come as a surprise, but there may be more than one IP associated with a host, just as there may be more than one host associated with an IP.<br />
<br />
 Usually, we only want the first address in this list of returned addresses to evade unnecessary complexity. That would be h_addr_list[0]. This, in past versions, was represented by h_addr; in order to maintain backward compatibility, a #define has been added to fudge this in Winsock 2.<br />
<br />
 [indent]<pre class='prettyprint'>struct hostent *host_addr;<br />host_addr = gethostbyname("gamedev.net");</pre><br />
[/indent] It is also possible to resolve an IP address into a host name. This can be done by passing a 32-bit integer representing the IP address in network byte order to the gethostbyaddr() function. As we have already discussed, the standard format for the IP address in written form is a decimal-point denoted set of four base-10 integers. It is for this reason that WinSock provides the inet_addr() function to convert an IP-address string to an appropriate unsigned long integer. gethostbyaddr() takes as its first parameter a pointer to a numeric IP [having been converted from a string with inet_addr()] in network byte order. Its second parameter is the length of the address, which is obviously sizeof(unsigned long), and its third parameter is the type of the address, which is obviously AF_INET in this case. Then the hostent structure's h_name field will contain the symbolic name of the host. As a side-note, the inet_ntoa is the converse of the inet_addr function.<br />
<br />
 [indent]<pre class='prettyprint'>struct hostent *host_addr;<br />host_addr = gethostbyaddr(inet_addr("127.0.0.0"), sizeof(unsigned long), AF_INET);</pre><br />
[/indent]<strong class='bbc'> Network and Host Byte-order</strong><br />
<br />
 This is not a very complicated subject. WinSock provides the functions htons(), ntohs(), htonl() and ntohl() for converting short ints (WORDs) and long ints (DWORDs) from and to host and network byte order, respectively. You should perform a ntohl() or ntohs() when appropriate for received data.<br />
<br />
<strong class='bbc'> Sending and Receiving Data</strong><br />
<br />
 One might expect this to be complicated and arcane. It's not. Let me give you a hint: The send() function sends data, and the recv() function receives it. Beyond this, there are a few specifics, but that's the general model that has been adopted.<br />
<br />
 First of all, it is important to make the distinction between connection-oriented and connectionless sockets. The connection-orientation of a socket is given by one of two things: Whether or not it wears baggy pants (ask Jim about that one), or what protocol it uses for communication. The UDP protocol obviously is not oriented at connections, as was already discussed. The question then arises as to how data is sent from a connectionless socket if there's no connection (because if there's no connection, we can't possibly know where to send the data TO).<br />
<br />
 To send data from a connectionless socket, we use the sendto() function, which allows us to specify this information. We can also use sendto() for connection-oriented sockets, but it's really not necessary to do so, because we already know where our data are supposed to go. Similarly, a recvfrom() function is provided. This function returns, in addition to whatever might be waiting for us to receive, relatively detailed information about the host sending the information to our socket.<br />
<br />
 So, with no further adieu, let's delve into these functions, which are really sort of the meat 'n potatoes of the entire WinSock development experience (...).<br />
<br />
 send() takes as its first parameter a socket descriptor. Its second parameter is a pointer to a buffer which will be sent. The third parameter is the length of the data in the buffer to be sent, in bytes. The fourth and final parameter is an arcane flag that specifies special conditions for how the data should be sent. It presently has two possible values, MSG_DONTROUTE and MSG_OOB. The "don't route" flag is self explanatory: It specifies that the sent information shouldn't be routed. Don't ask me how they manage that one. The other value relates to Out-Of-Band data, which is somewhat interesting but generally outside of our interests. (OOB data is any sort of data that has a higher priority or a separate meaning than the normal data transmitted in the datastream. In TCP, this is called urgent data. Because we're not really concerned with much except getting our data from one point to another on an internet as game programmers, we're not going to worry about it. If you'd really like to know about OOB data, for whatever reason, check out the section about "urgent data" in RFC 793 [the TCP RFC]).<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br />char *data = "Hello"<br />...<br /><br />//We'd create socket s somewhere in here and connect it<br /><br />...<br /><br />send(s, &data, 5, 0);</pre>[/indent] Well, one down. Three to go.<br />
<br />
 recv() is very similar to send(), with the exception that the buffer parameter (the second) is now to contain a pointer to a buffer which will be used to store whatever incoming data there happens to be from a remote socket. The third parameter is then the length of that buffer. The fourth parameter is, again, an obscure flag, this time with rather more useful values. MSG_PEEK can be passed as the flag parameter in recv() to copy the data from the socket's received buffer into the buffer specified, but to not remove that data from the socket's received buffer. MSG_OOB is also a valid flag here, and can be used to take a look at the OOB data coming in on this socket. It should be noted that recv() can be used on either connectionless or connection-oriented sockets. The only downside of using it on connectionless sockets is that you won't know where in Hades (or should I say Hayes?) the data that you've received is coming from.<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br />char data&#91;256&#93;;<br />...<br /><br />//We'd create socket s somewhere in here<br /><br />...<br /><br />recv(s, &data, sizeof(data), 0);</pre>[/indent] And then there were two...<br />
<br />
 The sendto() function is the next most intuitive in our little group, here. Its first four parameters have the same meaning as they do in the context of send(). The fifth parameter of sendto() gives the address of the remote host to send to. This is optional along with the last parameter when the socket that we're sending from is connected to another socket, but must be filled for anything meaningful to happen when our socket is connectionless. Note that this pointer is to a struct of type sockaddr, or in the case of TCP/IP, sockaddr_in.<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br />struct sockaddr_in addr;<br />char data&#91;256&#93;;<br />...<br /><br />//We'd create socket s somewhere in here and fill in addr<br /><br />...<br /><br />sendto(s, &data, sizeof(data), 0, &addr, sizeof(addr));</pre><br />
[/indent] Last but not least, recvfrom(): The hallmark of uselessness. The first four parameters of recvfrom() are the same as they were for recv(), and the last two are essentially the same as they were for sendto(), except that they're now "from" parameters that will hold the address of the remote host. The exception is that the last parameter of recvfrom(), for some ungodly reason, is a pointer to the size of the sockaddr_in structure which will hold the address of the remote host instead of a direct value for it. Don't ask me what genius thought that one up. Anyway, it should also be noted that the last two parameters are again optional.<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br />struct sockaddr_in addr;<br />char data&#91;256&#93;;<br />int x;<br />...<br /><br />//We'd create socket s somewhere in here<br /><br />...<br /><br />x = sizeof(addr);<br />recvfrom(s, &data, sizeof(data), 0, &addr, &x);</pre><br />
[/indent]<strong class='bbc'> How to get your sockets to listen()</strong><br />
<br />
 Aside from making them an offer that they can't refuse, the other way to get your sockets to listen is to use the listen() function (and you call this un-intuitive?). listen() has the main goal of getting a socket to listen for connections, and, if a connection is attempted, to add it to queue so that it can be processed and accepted by the accept() function (I know that I'm starting to see a pattern, here...)<br />
<br />
 In order for listen to have any meaning, two conditions must be met. First, a socket must be bound to a port on the local host. This is, as has already been discussed, achieved via the bind() function. Second, the socket must not be connected to a remote host at the time that it is listening for a connection. If you stop and think about it for a moment, this rather makes sense.<br />
<br />
 The first parameter of listen() is a socket descriptor of the socket which is to listen for incoming connections. The second parameter is the size of the backlog, or the queue to hold incoming connection requests, for the socket. There are numerous and creative ways to describe the backlog size parameter, but let it suffice to say that its maximum value is given by a constant SOMAXCONN. For our purposes, we may as well use this constant, although I highly doubt that (based upon the value of SOMAXCONN in Winsock 2) we will ever receive such a load of connections. The return value of listen() is 0 if no error occurs, and otherwise is 0.<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br /><br />...<br /><br />//create and bind socket s<br /><br />...<br /><br />listen(s, SOMAXCONN);</pre><br />
[/indent] Before accept() can be used, it is of course logical that the socket we wish to accept a connection on must be paying attention, i.e., listening. accept() is almost exactly the same as connect(), except that the second parameter, the pointer to a sockaddr_in structure, will get the address of the remote host instead of hold it, and the third parameter, this time for a worthy reason, is a pointer to an int that will get the length of the address returned. Note that the third parameter, in accordance with correct WinSock practices, should contain the sizeof the sockaddr_in structure on calling accept().<br />
<br />
 [indent]<pre class='prettyprint'>SOCKET s;<br />struct sockaddr_in addr;<br />int x = sizeof(addr);<br />...<br /><br />//create and bind socket s, then listen for connetions<br /><br />...<br /><br />accept(s, &addr, &x);</pre><br />
[/indent]<strong class='bbc'> Blockage and Synchronicity</strong><br />
<br />
 While the title of this section sounds rather like a prospective Tom Clancy novel, it's really a somewhat important issue. Up until this point, we have rather candidly ignored a fundamental question associated with all of the functions that we have explored. Let's consider the example of the recv() function. What would happen if there were no data to be received and we called recv()? If the connection had been closed on the other end, recv() would return politely and give us no data. However, if the connection is still intact, and the problem is simply that no data exists to be received, recv() would sit and wait for data to come in. This behavior of recv() defines it as a blocking function, one that blocks other code in a program from taking effect until it finishes. This is better stated by saying that recv() is a synchronous function as opposed to an asynchronous function.<br />
<br />
 In Berkley Sockets, this situation can be remedied by using the select() function. select() will take as its parameters a set of arrays of sockets to check for readability, the ability to write, error conditions, and other great things of the sort. Then, when something happens on one of these sockets, the event will be processed. This, while it worked fine and well for BSD, is not a very elegant solution under the Win32 development paradigm.<br />
<br />
 As a direct consequence of this problem, WinSock introduced asynchronous socket I/O functions that operate based upon the Windows messaging scheme. For once, I have to give credit to Win32 for introducing a better way of doing things.<br />
<br />
 The WSAAsyncSelect() function is the "control center" for the WinSock asynchronous socket support. It takes as its first parameter a socket descriptor. Its second parameter is the handle of a window whose WindowProc will receive control messages for the socket. The third parameter is very cool: It allows one to specify what message will be sent to one's WindowProc when an event does occur on a socket. The final parameter to WSAAsyncSelect() is a set of flags for events that a message will be sent on. Here's a table, straight from (well, slightly modified from) the documentation. I've taken the liberty of removing what is useless for the purposes of a game programmer.<br />
<br />
<p class='bbc_center'><strong class='bbc'>  WSAAsyncSelect Event Flags</strong><br />
</p><br />
<center><table border="3" cellpadding="0" cellspacing="0" width="90%"><tbody><tr><td class="tblhdr"><strong class='bbc'>Flag</strong></td><td class="tblhdr"><strong class='bbc'>Effect</strong></td></tr><tr><td>FD_READ</td><td>Notifies the window proc that data are waiting for the socket</td></tr><tr><td>FD_WRITE</td><td>Notifies the window proc that data can be sent from the socket</td></tr><tr><td>FD_ACCEPT</td><td>Notifies the window proc on an incoming connection request</td></tr><tr><td>FD_CONNECT</td><td>Notifies the window proc on a connection having been completed</td></tr><tr><td>FD_CLOSE</td><td>Notifies the window proc when the socket closes</td></tr></tbody></table></center><br />
These can be combined as any bit-flags can. In the WindowProc, when the socket event message is received, wParam will contain the socket to which the event pertains, the low word of lParam will contain the event code (from the table above), and the high word of lParam will contain whatever errors if any have occurred.<br />
<br />
 [indent]<pre class='prettyprint'>#define SOCKET_EVENT_HAS_HAPPENED   	25252<br /><br />SOCKET s;<br />HWND mywnd;<br /><br />...<br /><br />//create s and mywnd<br /><br />...<br /><br />WSAAsyncSelect(s, mywnd, SOCKET_EVENT_HAS_HAPPENED, FD_READ &#124; FD_WRITE &#124; FD_ACCEPT);</pre>[/indent] Note that there are a lot of details involved in the WSAAsyncSelect() function which I have neglected to cover. The basics discussed here are sufficient to attain decent use of WSAAsyncSelect() without too many problems. The rest is readily apparent from standard documentation.<br />
<br />
 In addition to WSAAsyncSelect(), asynchronous counterparts of the name service functions that we discussed a few sections back are also provided. These also require no elucidation, as they are a logical extension of their synchronous counterparts.<br />
<br />
<strong class='bbc'> Errors in WinSock</strong><br />
<br />
 The error-handling scheme in WinSock operates generally based upon return codes, but to figure out exactly what error has occurred, you need to call the WSAGetLastError() function when the return value of a function is non-zero (WSAStartup() would be the exception; it will return literally the error that has occurred if anything goes wrong). WSAGetLastError() takes no parameters and returns an integer error code.<br />
<br />
<strong class='bbc'> Cleaning up after yourself</strong><br />
<br />
 Upon exiting a WinSock application, it is a good practice to call the WSACleanup() function to clear up whatever you may have messed with in the course of the application itself. You should also use the closesocket() function, whose only parameter is a socket descriptor, to close a socket when you're done with it. There is no disconnect() function in Berkley Sockets; closing a socket is equivalent to disconnecting. However, in WinSock, it is possible to call WSADisconnect(), and it is generally polite to do so, but not required.<br />
<br />
<strong class='bbc'> What I didn't cover</strong><br />
<br />
 There is a lot more material regarding WinSock. What I have covered in this tutorial is what you need to know to use WinSock effectively for the purposes of a game programmer. If you want to know everything about every cubic centimeter of it, my only recommendation would be to go out and buy a reference on it. I cannot humanly be expected to accurately document the 84 functions in WinSock 2 and give detailed descriptions of their practical applications.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Coda</strong></span><br />
<br />
Well, I was going to present a demo with this article, but after it got to be over 50k, I decided that if it wasn't elicit enough, there's something wrong. I will use this space to send a message to the powers-that-be in article-writing: Help! I need assistance to complete this section. It took me a long time to put this documentation together, and it will take me even LONGER to cover the plethora of other standards out there. The present wish-list is for DirectPlay-related information and some demos. Anything you can throw together for this section would be greatly appreciated.<br />
<br />
 <span style='font-size: 18px;'><strong class='bbc'>Disclaimers</strong></span><br />
<br />
[1] If you don't like the use of the pronoun "his" in the general case, either append the English language or go back to the 13th century and bring Xena the Warrior Princess along.<br />
<br />
 [2] If you read this tutorial and find any errors within it, you should report them. It's no loss of face for me; I'd rather have errors exposed and corrected than ingrained in the minds of readers, only to be struck out with a blunt object when they get into an argument in a bad neighborhood over the role of GGP or ICMP or something of the sort ten years down the line.<br />
<br />
 [3] If you have any complaints or gripes with my style, my sense of humor, or anything relating to me or my existence, you can endulge yourself in fifty industrial-sized cans of "Beef-a-rooni", shove said complaints where the sun don't shine, and enrich the world with your beautiful music. Or, in short, write a better tutorial if you've got a problem with this one.<br />
<br />
 [4] Any copyright or trademark infringement in this document is probably intentional, and while it would be only ethical to sue me, the legal costs that you would incur in the process would far exceed my net worth.<br />
<br />
 Happy coding, finish that game, and send it over to GDW! ;)]]></description>
		<pubDate>Tue, 14 Sep 1999 11:57:23 +0000</pubDate>
		<guid isPermaLink="false">a941493eeea57ede8214fd77d41806bc</guid>
	</item>
</channel>
</rss>
