> For the complete documentation index, see [llms.txt](https://docs.proudnet.com/proudnet.eng/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.proudnet.com/proudnet.eng/proudnet/using_pn/server_client.md).

# Server and Client

## Start a server

To start the server, you first need to get a server object, as shown in the example below. As soon as you create the server, it will not start communicating with clients or create a thread pool right away, so you will need to call <mark style="color:orange;">Start</mark> on the created object to run the server.

### 1. Creating a server

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

<pre class="language-cpp"><code class="lang-cpp"><strong>m_netServer = Proud::CNetServer::Create();
</strong>// Healed objects can be removed with the delete operator. 
delete m_netServer;
</code></pre>

{% endtab %}

{% tab title="C#" %}

```csharp
Nettention.Proud.NetServer netServer = new Nettention.Proud.NetServer();
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Before starting the server, be sure to check the [**Server's UDP port type**](/proudnet.eng/proudnet/usage_pn/tips.md#how-the-server-uses-udp-ports)**.**
{% endhint %}

### 2. Preparation

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

```cpp
// Include the ProudNet.
#include “include\ProudNetServer.h”
  
// ProudNet is a namespace where all objects are grouped 
// under the name Proud.
using namespace Proud;
  
// port definition
int g_ServerPort = 33334;
```

{% endtab %}

{% tab title="C#" %}

```csharp
// Add to enable Proud
using Nettention.Proud;

// Define a port to use in advance
int serverPort = 33334;
```

{% endtab %}
{% endtabs %}

### 3. Starting a server

First, we create a server object and then call the <mark style="color:orange;">SetEventSink</mark> function. This is the process of registering an object to receive callbacks for events that happen on the server. You inherit from the <mark style="color:orange;">INetServerEvent</mark> object and pass a pointer to the object you created, and the server will callback events through this object.

{% hint style="info" %}
Starting with C++11, it is possible to register events using Lambda instead of <mark style="color:orange;">SetEventSink</mark>.
{% endhint %}

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

```cpp
// Please note that this is only for C++ 11 and earlier.
// g_eventSink is an object that inherits from INetServerEvent.
CNetServer* srv = 
         Proud::CNetServer::Create();
srv->SetEventSink(
         &g_eventSink);
  
// Set the parameters required to start the server.
CStartServerParameter p1;
 
// Port to receive the client's connection
p1.m_tcpPort = 33334;  
  
srv->Start(p1);
```

{% endtab %}

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

```cpp
// You can use it by registering logic to run as a Lambda on specific events.
srv->OnClientJoin = [...](CNetClientInfo* clientInfo) {
        // my event handler
        ...
};
```

{% endtab %}

{% tab title="C#" %}

```csharp
using namespace Nettention.Proud;
// NetServer, StartServerParameter omitting namespaces

NetServer netServer = new NetServer();

netServer.ClientJoinHandler = (clientInfo) => {
    // When the client connects to the server
};

// Registering additional events
...

StartServerParameter p1 = new StartServerParameter();
// You don't need to set the protocolVersion to use it.
p1.protocolVersion = "Same as the client protocolVersion";
// Enter the port number you registered above or enter it manually.
p1.tcpPorts.Add(serverPort);

netServer.Start(p1);
```

{% endtab %}
{% endtabs %}

:bulb:In the code example above, <mark style="color:orange;">g\_eventSink</mark> is the object created with the structure below.

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

<pre class="language-cpp"><code class="lang-cpp"><strong>// To create an object to receive events from CNetServer
</strong><strong>Class CServerEventSink 
</strong>         : public INetServerEvent 
{
       // When the Client's connection is complete, 
       // a callback occurs.
       // Takes a CNetClientInfo object as an argument. 
       Virtual void OnClientJoin(
           CNetClientInfo *info) 
           OVERRIDE
       {
           // Receive information from the Client  
           // and process it.
       }
       // When the Client's connection is disconnected, 
       // a callback occurs.
           Virtual void OnClientLeave(
               CNetClientInfo *info) 
               OVERRIDE
       {
               // Receive information from the Client  
               // and process it.
       }
       // Omit the rest of the Event
}
</code></pre>

{% endtab %}

{% tab title="C#" %}

```csharp
// In C#, you can use event handlers without creating a separate event object.

// Runs when a client connects to the server.
netServer.ClientJoinHandler = (clientInfo) =>
{
    Console.Write("Client {0} connected.\n", clientInfo.hostID);
};

// Runs when the client server connection is lost.
netServer.ClientLeaveHandler = (clientInfo, errorInfo, comment) =>
{
    Console.Write("Client {0} disconnected.\n", clientInfo.hostID);
};
```

{% endtab %}
{% endtabs %}

Receives a <mark style="color:orange;">CNetClientInfo</mark> object as an argument in the event that is callbacked. The <mark style="color:orange;">CNetClientInfo</mark> object contains the connected client information, and the <mark style="color:orange;">CNetClientInfo</mark> member <mark style="color:orange;">m\_HostID</mark> is the ID value that distinguishes each host.<br>

:bulb:<mark style="color:orange;">NetClientInfo</mark> in C# plays the same role as <mark style="color:orange;">CNetClientInfo</mark> in C++.

### 4. Disconnection

<table><thead><tr><th width="313">Functions</th><th>Description</th></tr></thead><tbody><tr><td>Stop</td><td>Server stopped. Disconnect all connections.</td></tr><tr><td>CloseConnection (Client's HostID)</td><td>Disconnect the corresponding client.</td></tr></tbody></table>

### 5. Start receiving client connections

In order to receive client connections on the server, we need to prepare a server-side <mark style="color:orange;">Listening Port</mark> and thread pool. To do this, we need to create a <mark style="color:orange;">Server</mark> object and call the <mark style="color:orange;">Start</mark> methods.

## Start a client

Like the server, the client can connect to the server after the object is created.

### 1. Creating a client

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

```cpp
m_netClient = Proud::CNetClient::Create();
```

{% endtab %}

{% tab title="C#" %}

```csharp
Nettention.Proud.NetClient netClient = new Nettention.Proud.NetClient();
```

{% endtab %}
{% endtabs %}

### 2. Preparation

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

```cpp
// Set the parameters required to connect to the server
Proud::CNetConnectionParam cp;

// You must enter the same protocol version as the server. You may not enter any at all.
cp.m_protocolVersion = g_version;
cp.m_closeNoPingPongTcpConnections=false;
cp.m_serverIP = _PNT("localhost");
cp.m_serverPort = 33334;	
```

{% endtab %}

{% tab title="C#" %}

```csharp
using Nettention.Proud;
// Omitting the NetConnectionParam namespace

// Set the parameters required to connect to the server
NetConnectionParam cp = new NetConnectionParam();

// Same protocol version as the server, does not need to be entered
cp.protocolVersion.Set(version);
// server address
cp.serverIP = "localhost";
// server port
cp.serverPort = 33334;
```

{% endtab %}
{% endtabs %}

### 3. Starting a client

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

```cpp
// Use the parameters created in the preparation example above.
m_netClinet->Connect(cp);
```

{% endtab %}

{% tab title="C#" %}

```csharp
// Use the parameters created in the preparation example above.
netClient.Connect(cp);
```

{% endtab %}
{% endtabs %}

#### Events that occur while a client is connecting to the server

> * When <mark style="color:orange;">Connect</mark> is executed, the server receives a <mark style="color:orange;">OnConnectionRequest</mark>, where it can reject clients attempting to connect.
> * Accepting the client connection in <mark style="color:orange;">OnConnectionRequest</mark> completes the connection process, the client and server receive codes like below example.

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

```cpp
// On the server
m_netServer->OnClientJoin = [](CNetClientInfo *clientInfo){
    // Logic to run on Client Join
};

// On the client
m_netClient->OnJoinServerComplete = [&](ErrorInfo *info, const ByteArray &replyFromServer) {
    // Logic to run on completion of Server connection
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
// On the server
netServer.ClientJoinHandler = (clientInfo) => {
    // Logic to run on Client Join
};

// On the client
netClient.JoinServerCompleteHandler = (info, replyFromServer) => {
    // Logic to run on completion of server connection
}
```

{% endtab %}
{% endtabs %}

### 4. Disconnection

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

```cpp
// Disconnect from the server
m_netClient->Disconnect();
```

{% endtab %}

{% tab title="C#" %}

```csharp
// Disconnect from the server
netClient.Disconnect();
```

{% endtab %}
{% endtabs %}

***

## Usage <a href="#server-client-usage" id="server-client-usage"></a>

{% content-ref url="/pages/aId6xnt3kOvkFQRH2qj9" %}
[Utilization of Server](/proudnet.eng/proudnet/using_pn/server_client/using_server.md)
{% endcontent-ref %}

{% content-ref url="/pages/b1BROqkBWO3ti0Lt6oI9" %}
[Utilization of Client](/proudnet.eng/proudnet/using_pn/server_client/using_client.md)
{% endcontent-ref %}
