The networking component of DirectX has undergone a major revision. DirectPlay introduces a new set of interfaces that enable games to have more direct access to the hardware, providing better performance.

The following list describes some of the new DirectPlay features.

Objects have been completely rewritten.

The complexity of creating a networked application has been dramatically simplified by separating the interfaces for creating peer-to-peer and client/server sessions. The objects for creating DirectPlay transport sessions are now:

Provides methods for creating the server-side portion of a client/server application.

Lobbying is now independent from the rest of DirectPlay.

DirectPlay has removed the requirement that a lobby client work only with a DirectPlay application. This will allow for either the lobby service provider or the application to implement DirectPlay without concern for the other. Lobby implementation is now separated into two simplified objects.

This object is used to register a lobby launchable application with the system so it can be lobby launched. It also is used to get the connection information from the lobby to enable game launching without querying the user.

Addressing information has moved from GUID-based data to URL-based data format.

Previous versions of DirectPlay used binary chunks of data with GUID addresses that were difficult to implement and that humans could not read. In DirectX 8.1, DirectPlay introduces the representation of addresses in URL format. DirectPlay provides an object that is used to create and manipulate the new addressing format.

Increases in consumer bandwidth have dramatically affected network game design and implementation. Improved DirectPlay thread-pool management makes it easier to for the developer to design scalable, more robust applications that can support massive multiplayer online applications.

Better support for firewalls and network address translators has been added.

Writing network games that traverse network address translators (NATs), firewalls, and other Internet connection sharing (ICS) methods can be difficult, particularly for non-guaranteed (UDP) traffic. Because DirectPlay 8.1 has been developed with these issues in mind, it will support NAT solutions where possible. The DirectPlay 8 TCP/IP service provider uses a single, developer-selectable UDP port for game data, making it possible to configure firewalls and NATs appropriately. Additionally, DirectPlay makes use of UDP so that, for client/server games, clients behind some NATs will be able to connect to games without additional configuration.

Test your application under a variety of network conditions with DP8Sim

You can now use a network simulator tool, DP8Sim, to help you predict how your application will perform under network conditions such as high latency or packet loss. DP8Sim is a simulated TCP/IP service provider applied on top of your existing network characteristics. A simple user interface (UI) allows you to easily change the simulated network settings and monitor your application's performance.

You communicate with a DirectPlay object by calling the methods exposed by its interfaces. For instance, to send some data to another user in a peer-to-peer game, you would send a message by calling the DirectPlay8Peer.SendTo method. DirectPlay then takes care of getting the message to its target.

DirectPlay communicates with your application through one or more message handlers. A message handler is an object that DirectPlay calls to notify your application of various events. The documentation describes the methods that are exposed by the object, but you must implement all of the objects methods in your application. You then register the object during startup, and DirectPlay will call the object's methods to notify you when an event has occurred. Additional information about the event is passed through the method's parameters.

1.2.4.DirectPlay的Lobby支持

A lobby is an application whose primary purpose is to enable players to meet and arrange games. It is typically located on a remote computer, and accessed over the Internet. Lobby servers often also perform a variety of other functions, such as hosting chat rooms, posting news and information, and selling merchandise. While lobby servers are convenient and commonly used to arrange multiplayer games, they aren't required. Multiplayer games can also be arranged by direct communication between lobby clients.

There are normally three components that are needed to enable a game to interact with a lobby:

¨A lobby server

¨A lobby client

¨A lobbyable game.

Microsoft® DirectPlay® does not specify how you should implement a lobby server application. Instead, DirectPlay provides support for a lobby client. A lobby client is an application that is implemented by a lobby server vendor, and installed on each user's system. It serves as a link between the user and the lobby. While you could handle such communication directly, you would have to know the specific implementation details of every lobby that might launch your game.

The lobby client application handles the details of communicating with its associated lobby server, using whatever protocols are appropriate. The lobby client communicates with the user and their game applications through a DirectPlay interface. DirectPlay then passes messages to the application. The application can also use a DirectPlay interface to pass messages to the lobby client.

A lobby can launch virtually any application. However, the application must have some specific lobby-aware components to take full advantage of lobby-launching. In particular, a lobbyable application can communicate with the lobby client throughout the course of the session. If an application is registered as lobbyable, the lobby client also automatically receives updates for various changes in game status, such as host migration.

1.2.5.DirectPlay语音通信

The current trend toward team-based multiplayer games makes player-to-player communication an essential part of game play. Historically this has been confined to text-based communication, where players type out the messages to their teammates. Although suitable for slower, turn-based games, text-based communication is at best an inconvenience for real-time games. Not only does it put slow typists at a disadvantage during game play but also it is a significant break in the reality that games attempt to create for the player. An obvious solution to the problem is the use of speech as a means for communication. It requires no training and increases the immersion of the game itself.

The Microsoft® Windows® platform provides all the tools required to provide real-time voice conferencing to video game developers, but it requires a significant amount of effort on the part of the game developer. This, combined with the cost and difficulty of obtaining the rights to compression technology capable of handling extremely low bandwidth situations, has prevented the widespread use of voice in games.

Microsoft DirectPlay® 8.1 provides the game developer with a robust real-time voice conferencing system that requires minimal effort to use.

Once you have selected a service provider, you can then create a DirectPlay address object for your user (a device address). You will use this address to identify your device with a number of DirectPlay methods. See DirectPlay Addressing for a detailed discussion of DirectPlay addresses and address objects.

1.3.1.3.为会话选择一个主机

Although most aspects of peer-to-peer games can be handled by the various users' communicating directly with each other, there are some tasks that must have a single owner. These tasks are handled by the game host. To join a session, you must know the address of the session's host. A common way to select a host is through a lobby server. In that case, when a user's application is connected to the session, the connection settings that you receive when Microsoft® DirectPlay® calls your DirectPlay8LobbyEvent.Connect method include the host's address object. To find out who the session host is:

¨If the DPLCONNECTSETTINGS_HOST flag is not set, then you can get the address of the host from the pdp8HostAddress member.

You can also create a broadcast session, perhaps on a LAN subnet, by advertising yourself as a session host. To do so call DirectPlay8Peer.SetPeerInfo to set the player's name and then call DirectPlay8Peer.Host to advertise yourself as a potential host. You specify the configuration of the game by assigning values the DPN_APPLICATION_DESC type that is passed through the pdnAppDesc parameter of IDirectPlay8Peer.Host.

To allow your user to examine the available sessions and hosts, you can enumerate the available hosts by calling DirectPlay8Peer.EnumHosts. Once the user has selected a session, you can request a connection.

1.3.1.4.连接到一个会话

除非你是会话的主机，否则你就必须将玩家连接到会话。为了实现这一点，你必须有会话中主机的地址。If your application was connected by a lobby client, you can obtain the host's address by calling DirectPlay8LobbiedApplication.GetConnectionSettings. You can also obtain the address by enumerating the available hosts. The information returned by the enumeration includes each host's addresses, and a DPN_APPLICATION_DESC structure that describes the associated session.

When a player attempts to join a session, the Microsoft® DirectPlay® calls the host's DirectPlay8Event.IndicateConnect method. To accept the player into the session, set the method's fRejectMsg parameter to False before returning. Setting fRejectMsg to True rejects the request. In either case, the player's DirectPlay8Event.ConnectComplete method will be called with the response. If the host accepted the connection, the hResultCode member of the DPNMSG_CONNECT_COMPLETE type will be set to 0. If the request was rejected or failed for some other reason, hResultCode will be set to an error code.

Once the new player is connected, DirectPlay announces the new player by calling DirectPlay8Event.CreatePlayer for each member of the session, including the host. The lPlayerID parameter contains the player ID that you will use to send messages to that player.

1.3.1.5.管理会话

The session host is responsible for managing the session, including:

¨Managing the list of session members and their network addresses

¨Deciding whether a new user is allowed to join the session.

¨Notifying all members when a new user joins the session, and passing them the new user's address.

¨Providing new users with the current game state

¨Notifying all users when a user leaves the session

When players attempt to join a session, Microsoft® DirectPlay® will call the host's DirectPlay8Event.IndicateConnect method. To accept the player into the session set fRejectMsg to False. Setting fRejectMsg to any other value rejects the request. In either case, DirectPlay calls the player's DirectPlay8Event.ConnectComplete method with the response to the request.

The host can remove a player from the session by calling DirectPlay8Peer.DestroyPeer. Other members of the session cannot call this method successfully. If you want to allow players to request that another player be removed from the session, you must send the request to the host, and have the host handle the request.

1.3.1.6.移动主机

While the host must be one of the initial members of the session, they may choose to leave before session is finished. When the host leaves the session, there are two possible outcomes:

¨会话终止。

¨转移主机，另一个用户成为主机。

Sessions may or may not permit host migration. To enable host migration, the session organizer must set the DPNSESSION_MIGRATE_HOST flag in the dwFlags member of the DPN_APPLICATION_DESC type when they set up the game. If this flag is not set, the session terminates when the host leaves or loses their connection.

If DPNSESSION_MIGRATE_HOST flag is set and the host leaves the session, Microsoft® DirectPlay® will select a new session host. DirectPlay will call the DirectPlay8Event.HostMigrate method of all remaining session members with the ID of the new host.

1.3.1.7.普通的对等网游戏

In Microsoft® DirectPlay® , a message is essentially a block of game-related data that you send to one or more members of the session. DirectPlay does not specify the contents or format of the data block, it just provides a mechanism to transmit the data from one user to another. Once the game is underway, each session member will normally send a constant stream of messages to all other members of the session for the duration of the game. The primary purpose of these messages is to keep the game state synchronized, so that each user's application displays the same UI. However, messages can also be used for a variety of other game-specific purposes.

For many games, especially rapidly changing ones, you may have to manage your messaging carefully. DirectPlay throttles outgoing messages to a level that can be handled by the target. You will have be careful that you do not send messages too rapidly, and ensure that the most important messages get through. See Basic Networking for a discussion of how to effectively handle DirectPlay messaging.

To send a message to another session member, call DirectPlay8Peer.SendTo. DirectPlay will call that members DirectPlay8Event.Receive method with the data. To send a message to a specific player, set the idSend parameter to the player ID that you when your DirectPlay8Event.CreatePlayer method was called. You can also send a message to every player in the session by setting idSend to DPNID_ALL_PLAYERS_GROUP. You can also define groups of players, and use a single SendTo call to send a message to all members of a group.

Note You can also use the DirectPlay8Peer.SetPeerInfo method to send information to other users. DirectPlay will call their DirectPlay8Event.InfoNotify method with the information. However, this way of transmitting information is not very efficient, and should not be used for normal messaging.

Using Groups

Many games allow players to be organized into groups. For instance, strategy games typically allow individual players to be organized into groups that can then be directed as a single entity. Microsoft® DirectPlay® also allows the formation of groups of players. DirectPlay groups are essentially a way to simplify your messaging. Once you have defined a group, you can send a message to every group member with a single DirectPlay8Peer.SendTo. While DirectPlay groups normally correspond to the groups that are defined by the game, you are free to create a group for any reason.

Once the group is established, you can send data to the group by calling DirectPlay8Peer.SendTo, with the idSend parameter set to the group ID. DirectPlay will call all group members' DirectPlay8Event.Receive method with the data.

To remove a player from a group, call DirectPlay8Peer.RemovePlayerFromGroup. DirectPlay will call the session members' DirectPlay8Event.AddRemovePlayerGroup method with the player's ID.

A client/server session consists of a collection of players, or clients, connected to a central server. As far as Microsoft® DirectPlay® is concerned, a client has no knowledge of any other clients, only the server. The messaging needed to run the game is between the individual clients and the server. DirectPlay does not provide direct client-to-client messaging, as it does for peer-to-peer sessions.

A client/server session requires two distinctly different applications.

¨The server application runs on a remote server. At a minimum, it serves as a central messaging hub and game host. The server must receive and handle all incoming messages from the clients, and send appropriate messages back out. Any transfer of data from one client to another must be handled by the server application.

¨A client application runs on each players' computer. The primary function of this application is to handle the UI, and keep the player's game state synchronized with the server.

There are certain aspects of the session that can be handled by only one of these applications. For instance, updating a player's video display can only be done by the client application. However, many aspects of the processing needed to maintain the game universe can, at least in principle, be done by either application. Writing an effective client/server game requires some careful consideration of how to divide the processing chores between the two applications.

This document describes the basic principles of client server games, and outlines how to implement client and server applications.

1.3.3.DirectPlay Lobbies

A client/server game can be launched through a lobby, or directly by the server application.

The Server Application

Client/server games are often arranged through lobbies. The most straightforward way to launch the server is to implement it as a lobbyable application. This approach provides a way to launch the server, and supports communication between server and lobby during the course of the session. See DirectPlay Lobbies for further discussion.

A server can also be directly launched, and then advertise itself as available and wait for clients to connect. See Selecting a Client/Server Host for details.

Once the server application has been launched, it should register it's DirectPlay8Event notification handler object. The DirectPlay8Event object is essentially an event handler that receives notifications from Microsoft® DirectPlay® . It is not provided by DirectPlay and must be implemented by your application. See the reference documentation for details. You should also call DirectPlay8Server.SetServerInfo to describe the current game. Clients cannot connect to a server until this method has been called.

The Client Application

One of the first steps you should take is to determine whether your game was lobby-launched. To do so, create a DirectPlay8LobbiedApplication object and a DirectPlay8LobbyEvent object. Register the DirectPlay8LobbyEvent object with Microsoft® DirectPlay® by calling DirectPlay8LobbiedApplication.RegisterMessageHandler. The DirectPlay8LobbyEvent object is essentially an event handler that receives notifications directly from the lobbied application object, and indirectly from the lobby client and the lobby. It is not provided by DirectPlay and must be implemented by your application. See the reference documentation for details.

If the application was lobby-launched, DirectPlay will call your DirectPlay8LobbyEvent.Connect method. The dlNotify parameter will contain a DPL_MESSAGE_CONNECT type with connection information. such as address objects for the members of the session.

The process of arranging and managing a session of a multiplayer game based on Microsoft® DirectPlay® involves five separate components. The lobby server application is a third-party application that typically resides on a remote server and is accessed through the Internet. The remaining four components are installed on each player's computer.

¨Lobby client. The lobby client is a third-party application that communicates with the lobby server. It also communicates with the user's game application through the DirectPlay lobby client object.

¨Lobbyablegame application. The lobbyable game application is a third-party application that uses the DirectPlay lobbied application object to communicate with the lobby client, and through the lobby client with the lobby server.

¨DirectPlay lobby client object.

¨DirectPlay lobbied application object.

The two DirectPlay objects act as links between the game application and the lobby client. They communicate with each other through private interfaces. The following graphic shows how these pieces are linked, and how they communicate.

1.3.3.2.Lobby Servers

The lobby server is an application whose primary purpose is to enable players to meet and arrange games. It is typically located on a remote computer, and accessed over the Internet. Lobby servers often perform a variety of other functions such as hosting chat rooms, posting news and information, and selling merchandise.

¨Managing the network addresses of the various game sessions and players.

¨Launching a session by launching the associated game applications on the players' computers.

¨Adding players to an ongoing session.

¨Connecting the various computers in a session to the correct network addresses.

¨Keeping track of changes in the session, such as players leaving the game or changes in the game's host.

The details of the lobby server application depend on what kind of services the vendor wants to offer. Microsoft® DirectPlay® does not specify how a lobby server should be implemented nor how it should communicate with its users' computers. However, lobby vendors must implement and distribute to their users a lobby client that is compatible with DirectPlay.

1.3.3.3.Lobby Clients

A lobby client is an application that is implemented by the lobby server vendor and installed on each player's computer. It handles communication between the players and their game applications, and the lobby server. A common way to install a lobby client is to have the user download it from the lobby server's Web site as part of the sign-up procedure.

The following is a typical scenario.

¨A new player goes to the Web site and signs up.

¨As part of the sign-up procedure, the lobby client is downloaded to the client's computer.

¨The player determines which game to play and asks to join a session.

¨The Web site launches the lobby client on the player's computer. A typical launch mechanism is a URL that points to the lobby client's executable file.

¨The lobby client handles the mechanics of arranging the session, and then launches the user's game application.

¨If the game is a lobbyable application, the lobby client enables the game application to communicate with the lobby server. This connection enables the lobby server to keep track of events such as players entering and leaving the game and host migration.

Lobby clients do not necessarily have to be linked to a remote server. In another scenario the user launches the lobby client directly. The lobby client then lists the available games and sessions, perhaps among the people connected to the user's LAN subnet. Once the user chooses a game and session, the lobby client launches the game.

This section discusses some of the general features of a lobby client. For more information on communicating between a lobby client and its associated lobby server, see Communicating with a Lobbied Application.

For more information on implementation details, see Implementing a Lobby Client or the LobbyClient sample application included in the SDK.

Communicating with a Lobby Client

Much of the lobbied application's interaction with an associated lobby client is indirect. The application does something that affects the lobby client, Microsoft® DirectPlay® sends an appropriate message, and vice versa. For instance, if the application changes the connection settings, DirectPlay notifies the lobby client, and provides the new settings. However, there are two methods that provide information directly to the lobby client: DirectPlay8LobbiedApplication.UpdateStatus and DirectPlay8LobbiedApplication.Send.

You must notify the lobby client when any of the following changes in the game status take place.

The DirectPlay8LobbiedApplication.Send method enables the application to send a message directly to the lobby client. DirectPlay passes the data to the lobby client without modification. It is the responsibility of the lobby client to process that data.

The lobby client can also send data directly to the application. DirectPlay passes the data to the lobby client's message handler by calling its DirectPlay8LobbyEvent.Receive method. DirectPlay passes the data to the application without modification. The lobby client must process the data.

1.3.3.4.Lobbyable Applications

Lobbyable applications are designed to work with a lobby client based on Microsoft® DirectPlay® . While a lobby client can use DirectPlay to launch any application, lobbyable applications have a number of advantages.

¨The lobby client can use a standard API to communicate with the application.

¨The application can use a standard API to communicate with the lobby client.

In short, DirectPlay virtually eliminates the need for game-specific or lobby client-specific communication code. You can use a standard API for everything with little or no modification for the particular game or lobby client.

One of the first things a lobbyable application should do after it is launched is create a DirectPlay8LobbiedApplication object. Among other things, this object enables your application to determine whether it was lobby-launched. A lobbied application must also implement a message-handler callback function to receive messages from the lobby client. The basic procedure is:

¨Create a DirectPlay8LobbiedApplication object.

¨Register a DirectPlay8LobbyEvent message handler object by calling DirectPlay8LobbiedApplication.RegisterMessageHandler. If the application was lobby-launched, DirectPlay will call your DirectPlay8LobbyEvent.Connect method. The dlNotify parameter will contain a DPL_MESSAGE_CONNECT type with connection information such as address objects for the members of the session.

Note The DirectPlay8LobbyEvent object is essentially an event handler that receives notifications directly from the lobbied application object, and indirectly from the lobby client and the lobby. It is not provided by DirectPlay and must be implemented by your application. See the reference documentation for details.

Once an application has been successfully lobby launched, Microsoft® DirectPlay® automatically sends status updates to the lobby client when events such as host migration occur. You can also use the lobbied application interface to send messages to the lobby client.

Be aware that your message handler object might be called by the lobby client before the initialization method returns. In addition to the connection message, the DirectPlay calls the object when the lobby client changes connection settings, or it breaks the connection. The lobby client can also send messages directly to your message handler that contain game-specific information.

1.3.4.Basic Networking

This section covers some basic networking technology topics that you need to understand to write Microsoft® DirectPlay® applications. For a general discussion of networking technology, see one of the standard texts on the subject, such as Computer Networks by Andrew Tannenbaum.

1.3.4.1.DirectPlay Service Providers

Microsoft® DirectPlay® provides your application with a virtual network connection that enables you to communicate with other computers in the same way, regardless of type of network involved. To provide this level of abstraction, network connections are made through a service provider. Once you have selected a service provider, your application uses the appropriate DirectPlay methods to communicate with other computers in a session. The service provider handles the details of communicating over the selected network hardware.

DirectPlay includes service providers for four types of network connections: TCP/IP, IPX, modem, and serial. See DirectPlay Addressing for a discussion of how to select a service provider.

Note To use modems on Microsoft Windows® 95 systems, you must install version 2.0 of the Telephony API (TAPI). You can download TAPI 2.0 from http://www.microsoft.com.

1.3.4.2.DirectPlay Addressing

To deliver messages, each participant in a multiplayer game must have a unique address. Addresses can refer to either the computer on which your application is running (device address) or a computer with which your application needs to communicate (host address).

Microsoft® DirectPlay® 8.1 represents addresses in the form of a URL string. The address string is then encapsulated in a DirectPlay8Address object that is passed as a parameter in or out of methods such as DirectPlay8Peer.Connect.

¨Handling Addresses discusses how to pass address objects in the Host, EnumHosts, or Connect methods.

¨DirectPlay Address Objects discusses how to manipulate the address string using the methods exposed by the address object's DirectPlay8Address class.

DirectPlay URLs

Microsoft® DirectPlay® represents addresses as URLs. In general, URLs are strings that consist of three basic components in the following order: scheme, scheme separator, and data string.

All DirectPlay addresses use "x-directplay" as the scheme, and ":/" (a colon followed by a forward slash) as the scheme separator. Using ":/" as a separator implies that the data that follows is opaque. In other words, the data string does not conform to any Internet standard and should be passed to the receiving application without modification. All DirectPlay URLs thus have the following general form.

x-directplay:/[data string]

Note Do not use "://" (a colon followed by two forward slashes) as a scheme separator. That separator implies that the data that follows conforms to an Internet standard and can be interpreted as such. To prevent confusion, DirectPlay flags any URL containing"://" as invalid.

Data Strings

The data string holds address information. The first part of a data string consists of a series of keyname=value elements separated by semicolons (;). You can include optional user data by putting a number sign (#) after the last value, followed by an application-defined string.

The key name is a lowercase string that identifies the data and implicitly indicates what type of data is contained in the value. For instance, the "provider" key name indicates that the value contains a Microsoft® DirectPlay® service provider GUID, in the form of a GUID string. The following characters are reserved and should not be used in value strings.

Ampersand (&)

Forward slash (/)

At sign (@)

Number sign (#)

Colon (:)

Question mark (?)

Equal sign (=)

Semicolon (;)

The first element in the data string must be the provider. Other elements can follow in any order. A generic URL looks something like this.

If you call the Host, EnumHosts, or Connect methods exposed by the DirectPlay8Peer, DirectPlay8Client, or DirectPlay8Server you must pass address objects as parameters. If Microsoft® DirectPlay® does not have sufficient address information, the method that you called will fail, and it will return DPNERR_ADDRESSING. However, it is not necessary to have all the information in the address object at the time you call the method.

All address objects must have the service provider GUID set. However, it is possible to omit other data values.

¨You can omit the device if the service provider supports all adapters.

¨You can omit the port number for IP and IPX service providers for the Host, EnumHosts, and Connect methods. DirectPlay will assign a port number. This number may vary.

¨If you set the OKTOQUERYFORADDRESSING flag, the service provider can display a dialog box asking the user for the information needed to complete the address. If the user does not supply sufficient information, the method will fail. If the OKTOQUERYFORADDRESSING flag is not set, no dialog box will be displayed. If the address you pass to the method is insufficient, the method will fail. In the last two cases, the error value that is returned will be DPNERR_ADDRESSING.

There are two important issues for IP and IPX service providers that you need to be aware of. Failing to handle them properly may cause your application to fail.

¨If you set the NOBROADCASTFALLBACK flag when you call an enumeration method, you must supply a hostname. If you do not do so, the method will fail and return DPNERR_ADDRESSING.

¨If you do not specify a port, do not assume that DirectPlay will always choose the same port number. The only way to be certain of the port number is to specify it in your address. If you do not specify a port number, you must retrieve the actual value later, after the command is in progress.

Note Application developers who choose to override the default DirectPlay 8 dialog for TCP/IP are strongly urged to implement a solution that allows the user to override the port used for a connection or enumeration. One possible solution is to enable users to follow the host name with a colon and then the port, as implemented by the default DirectPlay 8 TCP/IP dialog, for example: host.domain.com:8090. Another possible solution is to add a field to the UI that enables the user to enter a port.

DirectPlay Address Objects

Microsoft® DirectPlay® does not handle URL strings directly. Instead, the string must be encapsulated in a DirectPlay8Address object. This object exposes a number of methods that enable you to insert URL information into, or extract it from, the object.

To create DirectPlay address, you must first create a DirectPlay8Address object. You can then define the address in one of two ways:

¨Use other DirectPlay8Address methods to extract the particular data you are interested in from the address object.

1.3.4.3.DirectPlay Protocol

………

1.3.4.4.Optimizing Network Usage

Providing the best gaming experience normally means sending updates and other information as rapidly as possible without flooding the target with more messages than it can handle. The Microsoft® DirectPlay® protocol combined with asynchronous messaging enables you to dynamically optimize your messaging strategy to provide your users with the best possible game experience.

You can choose to send messages synchronously by setting the DPNSEND_SYNC flag. If you do so, the Send/SendTo method will block until the message is actually sent.

The DirectPlay protocol's throttling mechanism guarantees that the client will not receive messages faster than they can be handled. However, the throttling protocol does not control how frequently you submit messages to the outgoing queue. You can easily end up with a large backlog of messages in your unsent message queues. You can avoid this situation by sending messages as infrequently as possible, but then you might unnecessarily degrade the user's experience. An optimal messaging strategy sends messages as fast as possible without exceeding the target's ability to handle them.

The following are tips for optimizing your messaging strategy.

¨Send most if not all of your messages asynchronously. If you send a message synchronously, the method will block until the throttling mechanism allows the message to be sent.

¨Monitor the pending message queues and the network statistics. If there are few or no messages in the queue, you can increase your transmission rate. If the queues are large or growing rapidly, decrease your transmission rate and perhaps cancel some messages. See the discussion of send timeouts in Send Prioritization for more information.

¨Analyze the pending message queues on a player-by-player basis. Some players might be able to receive messages at a much higher rate than others. The bulk statistics might be misleading. Consider using directed sends rather than group sends.

¨Choose the appropriate category for each message. Reserve the categories with the highest overhead for the most important messages.

¨Prioritize your messages, so that the most important are assured of being sent promptly and not delayed by relatively unimportant messages.

¨Do not let the pending message queues grow too large. In addition to delaying the transmission of your messages, a large number of pending messages might consume significant memory resources.

¨Use the timeout feature of the Send and SendTo methods to automatically clear outdated messages from the pending message queue.

¨Minimize the amount of data per message. It is usually better to send frequent small messages than a smaller number of large messages.

¨Do not loop tightly when checking the pending message queue. Doing so wastes CPU cycles. Instead, use a sleep period based on how long it typically takes the queue to get down to the level that it will be ready for another send.

1.3.4.5.Network Address Translation, Firewalls, and Proxies

Network Address Translators (NATs), firewalls, and proxies pose similar challenges when designing a game that allows players on different computers to connect to each other. NATs are used to share a single Internet Protocol (IP) address between multiple machines. This means that a machine's internal IP address will be different from its external IP address, and can result in complications when using Microsoft® DirectPlay®. Firewalls and proxies are used to prevent unauthorized access to a network or machine and are usually designed to be transparent. This section describes how to properly configure your game to work with NATs, firewalls, and proxies.

NATs work best with applications where the server is not behind a NAT and the clients do not communicate directly with each other. If you want your application to run through any hardware or software NAT, you should follow these guidelines:

¨Either program your clients to enumerate the game's port directly without using DPNSVR, or connect directly without enumeration.

You can create an application that does not follow these guidelines, but it is not recommended.

In order for clients to enumerate the game's port directly, the client needs to know the host server's port. The client can get this knowledge through a third party, such as a matchmaking system, or the game can be programmed to use a particular port. Of the two options, using the third party is more flexible and is the better solution. If the server is not using a particular port, it should call the GetLocalHostAddress method to determine on what port it is hosting and communicate that information to the third-party matchmaking service.

A client enumerates the game's port directly by explicitly specifying the port number in the DirectPlay8Address object passed as the AddrHost parameter in the DirectPlay8Client.EnumHosts call as shown in the following example.

' Add host port to the address.

dph.AddComponentLong DPN_KEY_PORT, glDefaultPort' sComponent, lValue

...

' Enumerate host.

mlEnumAsync = moDPC.EnumHosts(Desc, dph,' ApplicationDesc, AddrHost

moDPA,' DeviceInfo

INFINITE,' lRetryCount

0, INFINITE,' lRetryInterval, lTimeOut

DPNENUMHOSTS_OKTOQUERYFORADDRESSING,' lFlags

ByVal 0&, 0)' UserData, UserDataSize

If you do use enumeration instead of connecting directly, you should keep the enumeration active and pass the host and device addresses indicated in the DPNMSG_ENUM_HOSTS_RESPONSE message without modification to the call to Connect. To do this, complete the following tasks.

¨Specify INFINITE for the lRetryCount parameter in the call to the DirectPlay8Client.EnumHosts method.

¨Store the address strings in a global location using threadsafe code.

¨Retrieve the address strings using threadsafe code when the user selects the session to join.

¨Pass the address strings into the call to Connect.

¨Release the references to the address strings when you are done.

DirectPlay will cancel the enumeration when the Connect method completes successfully. Do not call CancelAsyncOperation to end the enumeration unless the Connect method completes with a failure. For an example of how to store, retrieve, and release addresses using threadsafe code, see the code for the DirectPlay Samples.

If you want to allow end users to run their own servers, advise them not to put their game servers behind a NAT, or to explicitly configure their NAT to forward the game host's specific ports to the host machine. End users can also use Microsoft® Windows® Millennium Edition (Windows Me) or Microsoft® Windows XP Internet Connection Sharing (ICS) as their NAT to achieve this same result.

If your game is not able to follow these rules, for example if it is a peer-to-peer game, that game will have problems with most NATs. There is no way to implement a true peer-to-peer networking session where arbitrary users are behind arbitrary NATs. The behavior in this case is much improved when the end users are using Windows Me or Windows XP ICS as their NAT.

Some NATs perform special processing for particular applications or protocols. Windows ICS performs some special processing for DirectPlay. Different versions of Windows ICS perform different processing, depending on what version of DirectPlay was current at the time the Windows ICS was released.

Compatibility for Client/Server Games with NATs

The following sections discuss compatibility issues for client/server games depending on the NAT being used.

Multiple clients behind Windows 98 Second Edition ICS, Windows 2000 ICS, or third-party NATs that are not Universal Plug and Play (UPnP)-compliant can join a client/server game hosted by a server that is not behind a NAT, as long as the clients behind the NAT use direct host enumeration as described earlier. Clients behind non-UPnP NATs are more likely to be able to join a DirectPlay client/server game if the server is not behind a NAT and the clients use direct host enumeration.

DirectPlay might be able to support a server behind these NATs in some cases. However, the application will not work automatically. The end users will need to enable port forwarding. If you selected a port on which to host, they must manually configure their NAT to redirect traffic received externally to the internal host on that port. Be aware that you cannot have more than one server behind the NAT. If you do not select a port, they can attempt to enable port forwarding for the DPNSVR port 6073 and the game port. DirectPlay will usually select port 2302 for the game port, but if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). The user should consult the documentation for the NAT that they are using for information on setting up port forwarding.

Note Most NATs do not support enumeration through the DPNSVR port for client applications. This is because the client sends initial outbound traffic to the DPNSVR port, but the reply comes from the game port. Clients can attempt to enable port forwarding for the game port, but like servers, this design limits the user to only one client behind the NAT.

Windows Me ICS, Windows XP ICS, and UPnP-compliant NATs

Multiple clients behind a Windows Me ICS machine can join a client/server game hosted by a server not behind a NAT, even if the clients do not use direct host enumeration. However, the Windows Me ICS machine sometimes has problems joining games. The Windows Me ICS machine can usually join the game if it joins the session before any of the clients behind the ICS machine join the game. If the ICS machine does not join first, clients behind the ICS machine will be able to join but the client on the ICS machine might not be able to join.

Servers can be located inside the Windows Me ICS machine and still be seen from outside the NAT. No extra configuration is required in ICS or in the application.

Windows XP ICS and other UPnP-compliant NATs can also cooperate with DirectPlay and should not require extra configuration to support clients or servers behind the NAT. If you are having trouble hosting on a Windows XP ICS machine, be sure that the "Allow other network users to control or disable the shared Internet connection" box is checked.

No NAT can have multiple hosts using the same fixed port simultaneously. If you are using Windows Me ICS, Windows XP ICS, or UPnP-compliant third-party NATs and you specify a port already in use, you will receive the DPNERR_INVALIDDEVICEADDRESS return code when the Host method is called. You can allow DirectPlay to select a port and use DPNSVR enumeration or call the GetLocalHostAddress method to reach the session. Alternatively, you can allow your users to manually override the fixed port.

Note When hosting behind these NATs, the GetLocalHostAddress method returns the public address (the external interface on the NAT machine). Machines outside or inside the NAT can use this address to join the session. It does not return the address of the local network interface card (NIC).

Compatibility for Peer-to-Peer Games with NATs

The following sections discuss compatibility issues for peer-to-peer games depending on the NAT being used.

DirectPlay8Peer will not function properly through Windows 98 Second Edition ICS, Windows 2000 ICS, and third-party NATs that are not UPnP-compliant. However, you might be able to get some scenarios working, with the following considerations:

¨You might be able to join a peer-to-peer session from behind the NAT as long as you are the first player to connect to the session and the host does not migrate to you.

¨Explicitly configuring the NAT to forward ports may also allow hosting behind the NAT. If you selected a port on which to host, the end user must manually configure their NAT to redirect traffic received externally to the internal host on that port. If you do not select a port, they will need to enable port forwarding for the DPNSVR port 6073 and the game port. DirectPlay will usually select port 2302 for the game port, but if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). The user should consult their NAT's documentation for information on setting up port forwarding.

Note Most NATs do not support enumeration through the DPNSVR port for peer applications. This is because the peer sends initial outbound traffic to the DPNSVR port, but the reply comes from the game port. Peers can attempt to enable port forwarding for the game port, but like hosts, this design limits the user to only one peer behind the NAT.

Windows Me ICS, Windows XP ICS, and UPnP-compliant NATs

Windows Me ICS, Windows XP ICS, and UPnP-compliant NATs cooperate with DirectPlay to make it possible to run full-featured, peer-to-peer DirectPlay sessions through the NAT. Users can host or join DirectPlay sessions that are hosted inside or outside the NAT. No special configuration is required. Even host migration is fully functional.

However, the restriction for Windows Me ICS mentioned previously in the client/server case holds true—the client on the Windows Me ICS machine must join the session before any client behind the NAT joins the session or else the ICS machine will not be able to join.

As with client/server sessions, no NAT can have multiple hosts using the same fixed port simultaneously. The call to DirectPlay8Peer.Host will fail if the port is already in use on Windows Me ICS, Windows XP ICS, or UPnP-compliant NATs. See the client/server section for more information.

Note When hosting behind Windows Me ICS, Windows XP ICS, or UPnP-compliant NATs, the GetLocalHostAddress method returns the public address (the external interface on the NAT machine). Machines outside or inside the NAT can use this address to join the session. It does not return the address of the local NIC.

Using Firewalls and Proxies

Applications work best when the server is not behind a firewall or proxy and the clients do not communicate directly with each other. If you want your application to run through any hardware or software firewall, you should follow these guidelines.

¨Create client/server applications using the DirectPlay8Client and DirectPlay8Server interfaces.

¨Do not put servers behind a firewall or proxy.

¨Program your clients to either enumerate the game's port directly (not using DPNSVR) or to connect directly without enumeration.

You can create an application that does not follow these guidelines but it is not recommended.

Compatibility for Client/Server Games Using Firewalls and Proxies

The following sections discuss compatibility issues for client/server games, depending on the firewalls and proxies being used.

Windows XP Internet Connection Firewall

DirectPlay works with the Internet Connection Firewall (ICF) capabilities of Windows XP. When your application begins hosting, enumerating, or connecting, the appropriate ports will automatically open and when your application shuts down, these ports will automatically close. However, the user launching the application must be a member of the administrator group for the computer so that DirectPlay has the security permissions to open the ports.

Third-Party Firewalls

DirectPlay is unable to configure third-party firewalls automatically. Clients behind a third-party firewall should work if the firewall allows outbound UDP traffic.

To support servers behind a third-party firewall, end users will have to manually configure their firewall. If you select a port for the local device address, end users must configure their firewall to open that port. If you do not select a local port, end users need to attempt to open the DPNSVR port 6073 and the game port. DirectPlay usually selects port 2302 for the game port but, if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). Users should consult their firewall's documentation for information on opening ports.

Microsoft Internet Security and Acceleration Server and Third Party Proxies

DirectPlay works with the Microsoft Internet Security and Acceleration (ISA) Server and other proxies when running client applications. Clients that have the ISA Firewall Client software installed should not cancel the enumeration before connecting and should pass the address objects from the DPN_MSGID_ENUM_RESPONSE as described in the Using NATs section. If the enumeration is cancelled, the ISA Server can close the virtual connection established by the enumeration and the call to Connect will fail.

If you want to support a server application behind an ISA Server proxy, the end user must configure the ISA Server. If you have selected a port for the local device address, end users must configure the ISA Server to redirect traffic received externally to the internal host on that port. If you do not select a local port, end users can attempt to configure the ISA Server for the DPNSVR port 6073 as well as the game port. DirectPlay will usually select port 2302 for the game port, but if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). The user should consult the product documentation for how to configure their proxy.

Note Most proxies do not support enumeration through the DPNSVR port for client applications. This is because the client sends initial outbound traffic to the DPNSVR port, but the reply comes from the game port. Clients can attempt to enable port forwarding for the game port, but like servers, this design limits the user to only one client behind the proxy.

Compatibility for Peer-to-Peer Games Using Firewalls and Proxies

The following sections discuss compatibility issues for peer-to-peer games depending on the firewalls and proxies being used.

Windows XP Internet Connection Firewall

DirectPlay works with the Internet Connection Firewall (ICF) capabilities of Windows XP. When your application begins hosting, enumerating, or connecting, the appropriate ports will automatically open and when your application shuts down, these ports will automatically close. However, the user launching the application must be a member of the administrator group for their computer, so that DirectPlay has the security permissions to open the ports.

To support a host behind a third-party firewall, the end user will have to manually configure their firewall. If you select a port for the local device address, end users must configure their firewall to open that port. If you do not select a local port, end users can attempt to open the DPNSVR port 6073 and the game port. DirectPlay usually selects port 2302 for the game port, but if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). The user should consult their firewall's documentation for information on opening ports.

Microsoft Internet Security and Acceleration Server and Third Party Proxies

DirectPlay works with the Microsoft Internet Security and Acceleration (ISA) Server and other proxies when running peer applications. Peers that have the ISA Firewall Client software installed should not cancel the enumeration before connecting and should pass the address objects from the DPN_MSGID_ENUM_RESPONSE as described in the Using NATs section. If the enumeration is cancelled, the ISA Server can close the virtual connection established by the enumeration and the call to Connect will fail.

If you want to support a server application behind an ISA Server proxy, the end user must configure the ISA Server. If you have selected a port for the local device address, end users must configure the ISA Server to redirect traffic received externally to the internal host on that port. If you do not select a local port, end users can attempt to configure the ISA Server for the DPNSVR port 6073 as well as the game port. DirectPlay will usually select port 2302 for the game port, but if there are other DirectPlay applications running, it will select the next sequential port number available (for example, 2303). The user should consult the product documentation for how to configure their proxy.

Note Most proxies do not support enumeration through the DPNSVR port for client applications. This is because the client sends initial outbound traffic to the DPNSVR port, but the reply comes from the game port. Clients can attempt to enable port forwarding for the game port, but like servers, this design limits the user to only one client behind the proxy.

1.3.4.6.Using the DirectX Protocol in an Application

This section covers how you can use the features of the Microsoft® DirectPlay® protocol in your application.

Depending on which object your application is using to send messages, you send a message by calling a method named either Send, or SendTo. While the usage of these five methods is similar, they vary in detail. Refer to the appropriate reference pages for further discussion.

The Send/Sendto method's parameters might allow you to control many of the DirectPlay protocol's features. For example, the lFlags field of DirectPlay8Peer.SendTo allows you to specify:

¨The message's priority level.

¨Whether the message is reliable or unreliable.

¨Whether the message is sequential or non-sequential.

Refer to the appropriate method reference for further details.

When your application receives a message, DirectPlay will call your message handler's DirectPlay8Event.Receive method. The associated type contains a pointer to the data block, along with information such as the source of the message.