# 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 %}


---

# 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/using_pn/server_client.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.
