Connecting to other systems

Find who to connect to
There are 5 ways to find other systems to connect to:

1. Direct IP entry (you already know it)
2. LAN Broadcast
3. Using the SQLLite plugin as a directory server
4. Using the lobby server
5. Using DirectoryServer.php

Option 1: Direct IP Entry
The simplest and easiest way from a coding perspective is to either hardcode an IP address or domain name, or present a GUI to the user asking them to enter the IP address of the other system they would like to connect to. Most of the samples use this method. Back when networked games first came out, this was the only option provided.
Advantages:

- Little to no GUI work required of programmers and artists
- If the IP address or domain name is fixed, such as if you are running a dedicated server, this is the correct solution

Disadvantages:

- Inflexible
- Users will only be able to play with people they already know.

Note: Use 127.0.0.1, or localhost, to connect to another instance of RakPeer on the same computer, or the same application.

Option 2: Lan Broadcast

RakNet supports the ability to broadcast a packet to find other systems on a local LAN, with optional data to send and retrieve identifying the application. The sample LANServerDiscovery demonstrates this technique.
In RakPeerInterface.h, the Ping function will can do this, as follows
rakPeer->Ping("255.255.255.255", REMOTE_GAME_PORT, onlyReplyOnAcceptingConnections);
REMOTE_GAME_PORT should be whatever port the other system is running the application you care about on. onlyReplyOnAcceptingConnections is a boolean indicating if the other system should reply, even if they have no connections available for you to connect to.
Open systems will reply with ID_PONG. From the sample:
if (p->data[0]==ID_PONG)
{
RakNetTime time;
memcpy((char*)&time, p->data+1, sizeof(RakNetTime));
printf("Got pong from %s with time %i\n", p->systemAddress.ToString(), RakNet::GetTime() - time);
}
In order to send custom user data, call RakPeer::SetOfflinePingResponse(customUserData, lengthInBytes); RakNet will copy the data passed to it and return this data appended to ID_PONG.
Extending the example above to read custom user data:
if (p->data[0]==ID_PONG)
{
RakNetTime time;
memcpy((char*)&time, p->data+1, sizeof(RakNetTime));
memcpy(customUserData, p->data+1+sizeof(RakNetTime), p->length-1-sizeof(RakNetTime));
The +1 and -1 is the one byte ID_PONG.
Note: there is a hardcoded define MAX_OFFLINE_DATA_LENGTH in RakPeer.cpp limiting the length of your custom user data. Change this value and recompile if your data is larger than this define.
Advantages:

- You can join games automatically on program startup, no GUI or user interaction required
- Best way to find games on the LAN

Disadvantages:

- Won't work for the general internet
- Not as flexible as the lightweight database plugin

Option 3: SQLLite Plugin
The SQLLite3 plugin, found at DependentExtensions\SQLite3Plugin, contains the networking needed to make SQLLite work over the internet. The sample code has an implementation that will track all connections made to the server, allowing you to query the server for systems that have connected or disconnected. You can modify or update the sample to list game properties. This plugin provides functionality similar to the game listings you find on online services, or for first person shooters.
Advantages:

- Very flexible, can support any number of fields or datatypes
- Easy to find servers
- Automatically pings servers, and drops them off the list if they crash.

Disadvantages:

- Requires a separate, dedicated server to host the plugin
- Does not support persistent data, such as friends.
- SQL queries can be hard to write or setup in some cases

Option 4: Lobby Server
The lobby server provides a database driven service for players to interact and start games. It provides features such as friends, matchmaking, emails, ranking, instant messenging, quick match, rooms, and room moderation.
See the samples LobbyServerTest and LobbyClientTest for a demonstration of how to use this feature.
Advantages:

- The most flexible solution for players to join games
- Allows users to interact before starting games
- Builds community
- Supports multiple titles

Disadvantages:

- Requires a separate, dedicated server to host the plugin, and the server must have database support
- Feature is relatively large and complex compared to a simple game listing, requiring a good investment in time and programming

Option 5: DirectoryServer.php
DirectoryServer.php and related code can be found at Samples\PHPDirectoryServer. It is a cheap way to list games, by using your web server to store when a game was uploaded, and string based information about that game. For more information, see the manual page on this feature.
Advantages:

- Doesn't require a dedicated server, just a webpage

Disadvantages:

- Inflexible
- Sometimes unreliable (may require multiple queries)

Initiate connection attempt
Once you know the IP address of the remote system(s) to connect to, use RakPeerInterface::Connect() to initiate an asynchronous connection attempt. The parameters to connect are:
bool Connect( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, unsigned connectionSocketIndex=0 );

- host is an IP address, or domain name.
- remotePort is the port that the remote system is listening on, which you passed to the Startup() function
- passwordData is optional binary data to send with the connection request. If this data does not match what was passed to RakPeerInterface::SetPassword(), the remote system will reply with ID_INVALID_PASSWORD.
- passwordDataLength is the length, in bytes, of passwordData
- connectionSocketIndex is obsolete, do not use

Connect() will return true for a successful attempt, false if you are already connected to this system, a connection to the system is pending, the domain name cannot be resolved, incorrect parameters, internal error, or too many existing peers.
Note: Connect() returning true does NOT mean you are connected. If successful the message ID_CONNECTION_REQUEST_ACCEPTED should be received. If not you will recieve one of the error messages.

Troubleshooting connection failure

If ID_CONNECTION_ATTEMPT_FAILED is returned, this means you could not connect to that system. Possible reasons include:

- The IP address is wrong
- That system is not running RakNet, or RakPeerInterface::Startup() was not called
- The remote system has started RakNet, but RakPeerInterface::SetMaximumIncomingConnections() was not called
- A firewall on either system is blocking UDP packets on the port you have chosen
- A router on the remote system is blocking incoming UDP packets on the port you have chosen. See the NAT Punchthrough plugin to resolve this.
- On Windows Vista, the network driver security service pack sometimes breaks UDP, not just for RakNet, but in general, even for DirectPlay. This service pack should be rolled back, and not installed.
- Secure connections are enabled, and your system failed the security check.
- Your IP address was banned with RakPeerInterface::AddToBanList(). Note that some plugins, such as the connection filter, have the option to ban IP addresses automatically.

Assuming you are able to connect, it is time to go onto the section: Creating Packets

See Also

Index Connection Filter Creating Packets Lightweight Database plugin NAT Punchthrough plugin Secure connections FAQ