# Utilization of ProudNet

## ProudNet Server

The ProudNet server is an instance of <mark style="color:orange;">Proud::CNetServer</mark> and performs the following roles.\
It also acts as a relay server for P2P communication.

> * Accept and manage connections from ProudNet clients
> * Communicate with clients: RMI
> * Manage groups for P2P communication between clients: See [**P2P group**](/proudnet.eng/proudnet/using_pn/p2p.md#p2p-group)

## ProudNet Client

The ProudNet network client is an instance of <mark style="color:orange;">Proud::CNetClient</mark> and has the following roles.

> * Connecting/disconnecting from the server: See [**Connecting to the server from a client**](/proudnet.eng/proudnet/using_pn/server_client.md)
> * Communication with the server: RMI
> * P2P communication with other clients: RMI

<figure><img src="/files/yN06hgqknzEmx0EO9PHn" alt=""><figcaption><p>Client Server</p></figcaption></figure>

## ProudNet Protocol Types

The following messaging protocols are supported, and you can select one and put it as a parameter to your RMI function call.

<table><thead><tr><th width="217">Protocol types</th><th>Description</th></tr></thead><tbody><tr><td>Reliable messaging</td><td>The time for sending and receiving messages between hosts is longer than <strong>Unreliable messaging</strong>, but the order and arrival is guaranteed.</td></tr><tr><td>Unreliable messaging</td><td>The time for sending and receiving messages between hosts is shorter than <strong>Reliable messaging</strong>, but the order of sending and receiving messages may be distorted, and arrival is not guaranteed.</td></tr></tbody></table>

Communication protocols used by the <mark style="color:orange;">Client</mark> and <mark style="color:orange;">Server</mark>

<table data-full-width="false"><thead><tr><th width="233">Status</th><th width="188">Reliable P2P RMI</th><th width="151">Unreliable P2P RMI</th><th>Reliable C-S RMI</th><th>Unreliable C-S RMI</th></tr></thead><tbody><tr><td>Normal</td><td>Reliable UDP</td><td>UDP</td><td>TCP</td><td>UDP</td></tr><tr><td>Poor UDP communication between peers</td><td>Relay and Reliable UDP or TCP</td><td>Relay and TCP</td><td>TCP</td><td>UDP</td></tr><tr><td>Poor client-to-server UDP communication</td><td>Relay and TCP</td><td>Relay and TCP</td><td>TCP</td><td>TCP</td></tr></tbody></table>

{% hint style="info" %}

* <mark style="color:orange;">Reliable UDP</mark> is a ProudNet self-implemented feature.
* Relay is handled by the <mark style="color:orange;">Server</mark>.
  {% endhint %}

{% hint style="success" %}
**Tips for choosing a protocol**\
When developing the game for the first time, use <mark style="color:orange;">Proud.RmiContext.ReliableSend</mark> to send all messages to <mark style="color:orange;">Reliable messaging</mark>. And collect the history of sending and receiving RMI messages by referring to Accessing all RMI call points.

In a typical game program, 20% or fewer RMI message types account for 80% or more of the total sends and receives, so we look for RMIs that have a very high sending and receiving frequency and are okay with 20% or fewer losses and modify them to use Unreliable messaging.
{% endhint %}

## ProudNet Client-Server Communication

In ProudNet, communication between client and server is done on a message-by-message basis, with each message corresponding to one RMI call, allowing for both reliable and unreliable communication.

{% hint style="success" %}
**Reference**

[**RMI** ](/proudnet.eng/proudnet-note/dictionary.md#rmi)

[**Server-client**](/proudnet.eng/proudnet-note/notes/client_server_communication.md) [**communication**](/proudnet.eng/proudnet-note/notes/client_server_communication.md)
{% endhint %}

## ProudNet P2P Communication Performance

ProudNet is powerful because it goes beyond the ubiquitous hole punching and relaying techniques, and supports P2P reliable messaging like TCP with zero connection latency.\
It is tolerant of sensitive or faulty NAT devices, self-resolving overloaded P2P transmissions on low-speed Internet, and enforces messaging between clients immediately after a user requests a P2P communication connection (<mark style="color:orange;">Proud.CNetServerCreateP2PGroup</mark> or <mark style="color:orange;">Proud.CNetServer.JoinP2PGroup</mark>).

Some NAT devices lose external address mappings for the same internal address due to mismanagement; ProudNet minimizes this loss of mapping information by having different UDP sockets between clients and only attempting to hole-punch when absolutely necessary.

For example, if you have a P2P connection but are not actually communicating, you will not perform hole punching. Therefore, after calling <mark style="color:orange;">Proud.CNetServer.CreateP2PGroup</mark>, <mark style="color:orange;">Proud.CNetServer.JoinP2PGroup</mark>, the values of <mark style="color:orange;">Proud.RmiContext.m\_relayed</mark>, <mark style="color:orange;">Proud.CNetClientInfo.m\_RelayedP2P</mark>, and <mark style="color:orange;">Proud.CNetPeerInfo.m\_RelayedP2P</mark> will still be false, but will change to true when you start communicating.

On home computers with slower uploads compared to download speeds, such as ADSL or ADSL2+, hole punching may not be able to overcome the amount of traffic, causing the sending computer or NAT device on the sending end to fail.

In this case, ProudNet uses its built-in resolving capabilities to detect excessive sending from multicasting clients and distribute the multicast to relay servers.

A strategy for punching NAT holes is known as the "port prediction technique".\
This technique enables hole punching between symmetric NAT devices, but has the side effect of excessive port mapping.\
To minimize side effects, ProudNet initially refrains from excessive hole punching and then gradually switches to aggressive methods such as port prediction. Therefore, in some NAT devices, it takes a while to switch the route to direct P2P, but it is not a problem because it uses the hole-punching first and relay technique later.

{% hint style="success" %}
**Reference**

[**Hole Punching**](/proudnet.eng/proudnet-note/dictionary.md#hole-punching)

[**P2P communication** ](/proudnet.eng/proudnet/using_pn/p2p.md)
{% endhint %}

## ProudNet's performance with UDP communication

When using the UDP protocol, ProudNet employs techniques such as <mark style="color:orange;">Coalesce</mark> and <mark style="color:orange;">MTU discovery fail</mark> prevention to increase communication performance.

In low volume communications, such as LAN environments with latencies of 1 millisecond or less, the communication load appears to be greater than the actual RMI data capacity. However, in a WAN environment with increased communication volume or high latency, the communication load will be less than for low volume communication on a LAN.

<figure><img src="/files/wqln1BBIXo7pjoSgaUUA" alt=""><figcaption><p>Communication volume relationship as the number of RMI calls increases</p></figcaption></figure>

In Internet communications over 100km away, packets must pass through many different types of gateway devices.\
Each gateway has a different tolerable MTU size, but if the sending side exceeds the defined MTU size, ICMP packet fragmentation occurs.

Some users are afraid of ICMP attacks and set it to block all kinds of ICMP packets, which can cause MTU discovery to fail because it cannot handle ICMP packet fragments, eventually breaking UDP communication between the two hosts.

ProudNet has features to prevent this.

## Encrypted communication in ProudNet

ProudNet's encrypted communication protocol is very strong.

The message to be encrypted is encrypted with a <mark style="color:orange;">symmetric key</mark>, and the <mark style="color:orange;">symmetric key</mark> used at this time is encrypted with a <mark style="color:orange;">public key</mark> and exchanged between hosts. These encryption keys cannot be hacked by third parties because they are assigned unique values not only in the server and client, but also in P2P communication between clients.

Encrypted messages are also significantly different in their internal content each time they are sent to another host, blocking hacking attempts to retransmit the same or similar message after packet capture. However, use them properly because they are slower to process than non-encrypted messaging.

ProudNet uses 128-bit RSA as its asymmetric key algorithm and AES or Fast as its <mark style="color:orange;">symmetric key</mark> algorithm. RSA is too computationally intensive to use alone, so we use it in combination with a <mark style="color:orange;">symmetric key</mark> algorithm.

This provides encryption not only for client-to-server communication, but also for P2P communication, making it highly secure. In addition, the <mark style="color:orange;">symmetric key</mark> used in RMI are highly reliable because they are encrypted and exchanged with RSA algorithm <mark style="color:orange;">public key</mark> during the initial server connection.

<figure><img src="/files/m2gKMiUk0f1PGbl60dlh" alt=""><figcaption></figcaption></figure>

&#x20;

{% hint style="danger" %}
The custom fields in the <mark style="color:orange;">Proud::INetServerEvent::OnConnectionRequest</mark> event, which occurs during the ProudNet client's connection to the server, are not encrypted. Do not pass user information through them.
{% endhint %}

### - ProudNet Encryption Techniques

ProudNet offers different encryption capabilities based on performance and security levels.\
To send an encrypted message, you can select the desired encryption method in <mark style="color:orange;">Proud.RmiContext.m\_encryptMode</mark> as an argument to an RMI method call or <mark style="color:orange;">SendUserMessage</mark> series method.

{% tabs %}
{% tab title="C++" %}

```cpp
Proud::RmiContext rmiContext;
rmiContext.m_encryptMode = Proud::EncryptMode::EM_Secure;
// Example of a proxy function
Proxy.RequestLogon(Proud::HostID::HostID_Server, rmiContext, m_Name, password);
```

```cpp
Proud::RmiContext rmiContext;
rmiContext.m_encryptMode = Proud::EncryptMode::EM_Fast;
Proxy.RequestLogon(Proud::HostID::HostID_Server, rmiContext, m_Name, password);
```

&#x20;Alternatively, you can use it just as easily.

```cpp
Proxy.RequestLogon(Proud::HostID::HostID_Server,Proud::RmiContext::SecureReliableSend, m_Name, password); 
// Using EM_Secure
```

```cpp
Proxy.RequestLogon(Proud::HostID::HostID_Server,Proud::RmiContext::FastEncryptedReliableSend, m_Name, password); 
// Using EM_Fast
```

{% endtab %}

{% tab title="C#" %}

<pre class="language-csharp"><code class="lang-csharp"><strong>Nettention.Proud.RmiContext rmiContext;
</strong>rmiContext.encryptMode = Nettention.Proud.EncryptMode.EM_Secure;
// Example of a proxy function
Proxy.RequestLogon(Nettention.Proud.HostID.HostID_Server, rmiContext, name, password);
</code></pre>

```csharp
Nettention.Proud.RmiContext rmiContext;
rmiContext.encryptMode = Nettention.Proud.EncryptMode.EM_Fast;
Proxy.RequestLogon(Nettention.Proud.HostID.HostID_Server, rmiContext, name, password);
```

```csharp
Proxy.RequestLogon(Nettention.Proud.HostID.HostID_Server,Nettention.Proud.RmiContext.SecureReliableSend, name, password); 
// Using EM_Secure
```

```csharp
Proxy.RequestLogon(Nettention.Proud.HostID.HostID_Server,Nettention.Proud.RmiContext.FastEncryptedReliableSend, name, password); 
// Using EM_Fast
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If you are using the encryption feature in a P2P Group, you must set the value of <mark style="color:orange;">CStartServerParameterBase::m\_enableP2PEncryptedMessaging</mark> to **true**.

In C#, you can use <mark style="color:orange;">StarSeverParameterBase.enableP2PEncryptedMessaging</mark>.
{% endhint %}

### - Encryption key length: Balancing encryption level and performance

As part of ProudNet's encryption process, a key exchange takes place internally between hosts. The length of the exchanged keys can be set by the user, which should be set considering the performance of the system and the level of encryption.<br>

The length of the encryption key can be set at server startup in the parameters <mark style="color:orange;">Proud.CStartServerParameter.m\_encryptedMessageKeyLength</mark> and <mark style="color:orange;">Proud.CStartServerParameter.m\_fastEncryptedMessageKeyLength</mark>.

> * <mark style="color:orange;">Proud.CStartServerParameter.m\_encryptedMessageKeyLength</mark> parameter
>
> Refers to the length of the key when using AES encryption, and you can set the key length for <mark style="color:orange;">Proud.EncryptLevel.EncryptLevel\_Low</mark>, <mark style="color:orange;">Proud.EncryptLevel.EncryptLevel\_Middle</mark>, and <mark style="color:orange;">Proud.EncryptLevel.EncryptLevel\_High</mark>.
>
> &#x20;
>
> * <mark style="color:orange;">Proud.CStartServerParameter.m\_fastEncryptedMessageKeyLength</mark> parameter
>
> This is the length of the key when using the Fast method of encryption, and you can set the key length for <mark style="color:orange;">Proud.FastEncryptLevel.FastEncryptLevel\_Low</mark>, <mark style="color:orange;">Proud.FastEncryptLevel.FastEncryptLevel\_Middle</mark>, and <mark style="color:orange;">Proud.FastEncryptLevel.FastEncryptLevel\_High</mark>.

AES encryption is slightly slower than Fast, but provides a higher level of encryption.

However, for non-critical data like character movement messages, or messages that are sent and received a lot, you can use Fast, which has faster performance.

### - Performance comparison of ProudNet's Fast AES algorithm

The following is a comparison of the performance of ProudNet's Fast AES algorithm, measuring the time it took to perform 100,000 decryptions using each algorithm, at one decryption per time.

<figure><img src="/files/k1Tw4Phlu6vmHW1TEqqC" alt=""><figcaption><p>Performance comparison of the ProudNet Fast AES algorithm</p></figcaption></figure>

**Test specifications**

<table><thead><tr><th width="175" align="center">Items</th><th>Specification</th></tr></thead><tbody><tr><td align="center">OS</td><td>Windows 7 Professional K</td></tr><tr><td align="center">CPU</td><td>Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz 3.40GHz</td></tr><tr><td align="center">RAM</td><td>16.0GB</td></tr><tr><td align="center">System type</td><td>64-bit Operating System</td></tr></tbody></table>

{% hint style="success" %}
**Reference**

[**Encryption and Decryption**](/proudnet.eng/proudnet-note/notes/encryption_decoding.md)
{% endhint %}

## ProudNet message compression feature

In ProudNet, messages can be sent compressed, which is efficient by reducing the amount of communication and CPU usage on the host. To compress a message, set the argument <mark style="color:orange;">Proud.RmiContext.m\_compressMode</mark> to a value other than <mark style="color:orange;">Proud.CM\_None</mark> when calling an RMI method or when calling the <mark style="color:orange;">SendUserMessage</mark> method.

{% tabs %}
{% tab title="C++" %}

```cpp
Proud::RmiContext rmi = Proud::RmiContext::ReliableSend;
rmi.m_compressMode = Proud::CompressMode::CM_Zip;
 
Proxy.SendFileChunk(Proud::HostID::HostID_Server, rmi, dataBlock);
```

{% endtab %}

{% tab title="C#" %}

```csharp
Nettention.Proud.RmiContext rmi = Nettention.Proud.RmiContext.ReliableSend;
rmi.compressMode = Nettention.Proud.CompressMode.CM_Zip;
 
Proxy.SendFileChunk(Nettention.Proud.HostID.HostID_Server, rmi, dataBlock);
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.proudnet.com/proudnet.eng/proudnet/usage_pn.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
