The following steps show the overall flow of P2P communication.
This chapter only explains initialization, session management, and shutdown for P2P communication over the Internet. For more information about NEX peer-to-peer communication, see the NEX P2P Programming Manual.
To start Internet peer-to-peer (P2P) communication, use the ConnectivityManager::StartNATSession
function to automatically select the ports for P2P communication and initialize the NAT traversal feature, and then generate a NetZ class object to manage P2P communication. (For more information, see Code 8.1.)
Configure the P2P communication settings as needed after creating the NetZ class object. The following settings are required.
Network::SetP2PDataPacketSessionSignatureKey
function.
Code 8.1 Initializing NetZ
void InitializeNetZ(const nn::nex::qVector<qByte>& sessionKey)
{
if (pNetZ)
{
return;
}
nn::nex::CallContext oContext;
if(!nn::nex::ConnectivityManager::GetInstance()->StartNATSession(&oContext))
{
return;
}
oContext.Wait(); // Actually, the Dispatch process is repeated periodically.
if(!oContext.GetOutcome())
{
return;
}
NetZ pNetZ = qNew NetZ();
// Configure P2P communication settings as necessary.
Station::SetLocalPlayerName(_T("PLAYER NAME"), 0);
Network::GetInstance()->SetP2PDataPacketSessionSignatureKey(sessionKey);
}
With the StartNATSession
function, the names of NAT type detection server addresses are resolved. If the cable on the WAN side of the router is unplugged before name resolution, we recommend calling asynchronously because it takes up to 30 seconds to wait for the address resolution process to timeout. Also, because name resolution cannot be canceled, it takes up to 30 seconds if terminating NEX with address resolution in a state of non-completion after the StartNATSession
function.
When finalizing P2P communication, call NetZ::Terminate
to terminate the session, and then destroy the NetZ class object. After that, use the ConnectivityManager::StopNATSession
function to release ports. If you attempt to delete the NetZ object before terminating a session, processing blocks until an internal call to the NetZ::Terminate
function has completed, as seen in the following code example.
Code 8.2. Finalizing NetZ
void FinalizeNetZ(nn::nex::NetZ pNetZ)
{
if (!pNetZ)
{
return;
}
// If Terminate is not called, processing blocks until the NetZ object is deleted.
nn::nex::CallContext oContext;
pNetZ->Terminate(&oContext);
oContext.Wait();
qDelete pNetZ;
nn::nex::ConnectivityManager::GetInstance()->StopNATSession();
}
A P2P session must be created by a matchmaking session host. Use the Session::CreateSession
function to create a P2P session. You can optionally pass a session name in as one of this function's arguments. Specify the default value of true
as the second argument.
Code 8.3. Session Creation Function
static qBool CreateSession(const qChar *szSessionName=NULL,
qBool bNetworked=true);
Use the MatchMakingClient::GetSessionURLs
function to get the URL of the matchmaking session host, and then use the Session::JoinSession
function to join the P2P session. Leave the matchmaking session if you fail to join the P2P session.
Code 8.4. Joining a P2P Session
// Join a peer-to-peer session.
qBool JoinMachmakeSession(
NetZ* pNetZ,
MatchmakeExtensionClient *pMatchMakingClient,
GatheringID sessionGid)
{
qList<StationURL> lstURLs;
ProtocolCallContext oContext;
// Get the host URL.
if (!pMatchMakingClient->GetSessionURLs(&oContext, sessionGid, &lstURLs))
{
return false;
}
oContext.Wait();
// Confirm that at least one URL has been saved.
if(!oContext.GetOutcome() || lstURLs.empty())
{
return false;
}
if(!pNetZ->JoinSession(&oContext, lstURLs))
{
return false;
}
oContext.Wait();
return oContext.GetOutcome();
}
Warning
All URLs in the list obtained with the MatchMakingClient::GetSessionURLs
function are required. Pass to the Session::JoinSession
function without processing.
NAT traversal is a feature for establishing P2P communication in an environment that uses network address translation (NAT). Although NEX supports NAT traversal by combining all NAT types, NAT traversal is not supported under some network configurations. Although application developers do not need to be aware of this when implementing code, this chapter describes how to solve problems that may arise during development and debugging.
NEX uses separate UDP sockets for server communication and P2P communication. When several devices are connected on the same LAN, the port numbers used for both server communication and P2P communication are selected randomly to avoid port number conflicts.
If port numbers conflict, NAT assigns different port numbers. How port numbers are assigned is also dependent on the implementation of NAT. Although standard server communication does not have this problem, it must be avoided for P2P communication because it is important to predict which port the peer is sending packets from.
The socket used for server communication is re-created every time the local user logs in, while the socket used for P2P communication is re-created every time a NAT session starts (every time matchmaking is performed). In both cases, the sockets are then bound to a random port number. The same range of port numbers, 49,152 through 65,535, can be assigned for both server communication and P2P communication.
Note
The UDP-9103 port is used for communication with the friend server (fixed).
Note
Although http or https communication is performed when using NEX, TCP sockets are not used directly.
With NEX, NAT types are classified according to two mapping types and two filtering types. A total of four NAT types are possible by combining mapping types and filtering types. This example assumes a client IP address of 192.168.0.1, an IP address of 10.10.10.1 assigned to the global side of NAT, and two peer addresses of 10.10.10.10:10000 and 10.10.10.11:10000.
The mapping type is determined based on changes in the source port assignment when packets are sent in order to two addresses.
If packets are sent to different addresses from the same local source port, mapping is performed so that the global source port after overwriting is the same.
[192.168.0.1:10000:10.10.10.10:10000]→[10.10.10.1:10000:10.10.10.10:10000]
[192.168.0.1:10000:10.10.10.11:10000]→[10.10.10.1:10000:10.10.10.11:10000]
If packets are sent to different addresses from the same local source pot, mapping is performed so that the global source port after overwriting is different.
[192.168.0.1:10000:10.10.10.10:10000]→[10.10.10.1:10000:10.10.10.10:10000]
[192.168.0.1:10000:10.10.10.11:10000]→[10.10.10.1:10001:10.10.10.11:10000]
After a packet is sent to an address, the filtering type determines whether packets received at other ports at that address are filtered by NAT. The following example assumes that a particular type of server program is running at 10.10.10.10:10000
, and that when a packet is received responses are returned from the two ports 10000
and 10100
. If the terminal sends a packet to 10.10.10.10:10000 under these conditions, the following packets can be observed on the LAN side of the terminal.
[192.168.0.1:10000:10.10.10.10:10000] // Send from the terminal.
[10.10.10.10:10000:192.168.0.1:10000]
// First response from the server.
[10.10.10.10:10100:192.168.0.1:10000]
// Second response from the server.
[192.168.0.1:10000:10.10.10.10:10000] // Send from the terminal.
[10.10.10.10:10000:192.168.0.1:10000]
// First response from the server.
// Second response from the server was not received.
Generally, even though using PIF provides higher NAT traversal performance than EIM and PDF, which is better than EDM, all NAT type combinations are supported.
You can get the network NAT type during connection by executing a connection test for Internet settings from the 3DS System Settings. The upper 2 digits of the support code (the value shown in the lower right of the upper screen) that is acquired with the connection test is associated with the NAT type. The correspondence is shown in Figure 8.1. For example, when the support code is 110
, the type is EIM-PIF
.
Figure 8.1. Correspondence Between Support Codes and NAT Types
Also, the Wii U connection test performs NAT type determination twice, and determines whether port prediction is possible for EDM. The lower two digits of the support code indicate the results.
NEX does not support the following network configurations. Although clients with these network configurations can log in to the game server, attempts to join P2P sessions fail.
Because the implementation of the application does not change this functionality, the developer does not need to be aware of these limitations during implementation. However, in some cases problems are emphasized if debugging is performed during development with a large number of clients connected to a small number of routers. Be sure to check the network configuration if there are problems with clients joining P2P sessions.
CONFIDENTIAL