Raised This Month: $32 Target: $400
 8% 

[ANY] Using Socket Extension to send paquets between servers !


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 08-26-2015 , 03:08   [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #1

Using Socket Extension to create a server <-> clients connection



This is what we want to have as result
Exemple of plugin using this methode


Keywords
Server : When using the word 'server' I mean, the game server who will handle the clients request.
Clients : When using the word 'client' I mean, the game server who will connect and answer to the server request.

Introduction
In this small tutorial, I'm going to try to explain you how you can send and receive data over servers using the socket extension.

The schema above represent how our server will handle client request.
The blue arrow represent data being send by the server, the gree arrow represent data being send by the client.

So, if "client 2" send "hello" to the server, the server will read the data and send to all other clients ("client 1", "client 3", "client 4") "hello" as well.

If you understand this, go ahead and continue to read.

Creating the server
And now, enough theory, let's practice !

It's god damn important to read the orange line !!

Step 1) Plugin is empty, you got nothing :
PHP Code:
#include <sourcemod>
#include <sdktools>
#include <socket> //Obviously, we have to include the socket.inc file to our project.

#define PLUGIN_AUTHOR "Arkarr"
#define PLUGIN_VERSION "1.00"

public Plugin myinfo 
{
    
name "[ANY] A simple test for sockets",
    
author PLUGIN_AUTHOR,
    
description "A simple exemple plugin for introducing to socket",
    
version PLUGIN_VERSION,
    
url "http://www.sourcemod.net"
};

public 
void OnPluginStart()
{
    

Step 2) Creating the handles
PHP Code:
#include <sourcemod>
#include <sdktools>

#define PLUGIN_AUTHOR "Arkarr"
#define PLUGIN_VERSION "1.00"

Handle serverHandle;        //Handle to server, allow us to acces it from everywhere in the plugin
Handle ARRAY_Connections;    //Handle to connections, so we can store the client's connections.

public Plugin myinfo 
{
    
name "[ANY] A simple test for sockets",
    
author PLUGIN_AUTHOR,
    
description "A simple exemple plugin for introducing to socket",
    
version PLUGIN_VERSION,
    
url "http://www.sourcemod.net"
};

public 
void OnPluginStart()
{
    
ARRAY_Connections CreateArray(); // Init the array

Step 3) Detect if game server is the server
PHP Code:
#include <sourcemod>
#include <sdktools>

#define PLUGIN_AUTHOR "Arkarr"
#define PLUGIN_VERSION "1.00"

Handle serverHandle;        //Handle to server, allow us to acces it from everywhere in the plugin
Handle ARRAY_Connections;    //Handle to connections, so we can store the client's connections.

Handle CVAR_MasterChatServer//Allow the user to set if the game server is the server or a client
bool isMasterServer//Define if the game server is a server or a client
public Plugin myinfo 
{
    
name "[ANY] A simple test for sockets",
    
author PLUGIN_AUTHOR,
    
description "A simple exemple plugin for introducing to socket",
    
version PLUGIN_VERSION,
    
url "http://www.sourcemod.net"
};

public 
void OnPluginStart()
{
    
CVAR_MasterChatServer CreateConVar("sm_csc_is_server""0""Is this server the server ? 1 = yes | 0 = no, it's a client"_true0.0true1.0);
    
ARRAY_Connections CreateArray(); // Init the array
}

public 
void OnConfigsExecuted()
{
    
isMasterServer GetConVarBool(CVAR_MasterChatServer);
    
    if(
isMasterServer)
        
CreateServer();    //If the game server is a server, create the server
    
else
        
ConnecToMasterServer(); //If the game server is not the server, connect to the server (so it's a client)

Step 4) Initialise the server
PHP Code:
//Create the server, not that hard, hu ?
stock void CreateServer()
{
    
serverSocket SocketCreate(SOCKET_TCPOnServerSocketError);
    
SocketBind(serverSocket"0.0.0.0"2044); //Listen everything on port 2044
    
SocketListen(serverSocketOnSocketIncoming);    //On SocketIncoming will fire when a client connect to the server !

Step 5) What to do with clients ?!
PHP Code:
//When someone sucessfully connected to the server :
public OnSocketIncoming(Handle socketHandle newSocketchar[] remoteIPremotePortany arg)
{
    if(
isMasterServer//This is the job of the server, he have to handle clients :
    
{
        
PrintToServer("Another server connected to the chat server ! (%s:%d)"remoteIPremotePort);
        
SocketSetReceiveCallback(newSocketOnChildSocketReceive);            //When a client send a data, go inside of the 'OnChildSocketReceive' function.    
        
SocketSetDisconnectCallback(newSocketOnChildSocketDisconnected);    //When a client disconnect, go inside of the 'OnChildSocketDisconnected' function.
        
SocketSetErrorCallback(newSocketOnChildSocketError);                //When a client crash, go inside of the 'OnChildSocketError' function.
        
PushArrayCell(ARRAY_ConnectionsnewSocket); //Save the handle to the connection into a array to send futur messages
    
}

Step 6) OnServerSocketError / OnChildSocketReceive / OnChildSocketDisconnected / OnChildSocketError
PHP Code:
//When the server crash, we can't do something but wait for a admin to reload the plugin.
public OnServerSocketError(Handle socket, const int errorType, const int errorNumany ary)
{
    
LogError("socket error %d (errno %d)"errorTypeerrorNum);
    
CloseHandle(socket);
}

//When a client sent a message to the server OR the server sent a message to the client :
public OnChildSocketReceive(Handle socketchar[] receiveData, const int dataSizeany hFile)
{
    
PrintToServer(receiveData); //In any case, always print the message
    
    
if(isMasterServer//If the game server is the server, then send the message to all clients
        
SendToAllClients(receiveDatadataSizesocket);
}

//When a client disconnect
public OnChildSocketDisconnected(Handle socketany hFile)
{
    if(!
isMasterServer)
    {
        
PrintToServer("Lost connection to server");
    }
    
CloseHandle(socket);
}

//When a client crash :
public OnChildSocketError(Handle socket, const int errorType, const int errorNumany ary)
{
    
LogError("child socket error %d (errno %d)"errorTypeerrorNum);
    
CloseHandle(socket);

Our server is now ready ! He can handle clients and send message to others ! Cool. But without clients, nothing happens ! Let's see how we can fix that :

Creating and connectings clients !

Here we go, clients are a bit easier to handle, since they just receive and send data and do nothing else.
Remember the step 3) on 'creating the server part' ? Well there was a stock called :
step 1) ConnecToMasterServer
PHP Code:
//Connect to the server
stock void ConnecToMasterServer()
{
    if(
isMasterServer//Should never happen, but yeah..
        
return;
        
    
clientHandle SocketCreate(SOCKET_TCPOnClientSocketError); //Create the socket
    
PrintToServer("Attempt to connect to %s:%i ...""yourgameserver.com"2044);  //Simple message...
    
SocketConnect(clientHandleOnClientSocketConnectedOnChildSocketReceiveOnChildSocketDisconnected"yourgameserver.com"2044); //Set callbacks for clients    

step 2) OnClientSocketError / OnClientSocketConnected / OnChildSocketDisconnected
PHP Code:
//When the client crash
public OnClientSocketError(Handle socket, const int errorType, const int errorNumany ary)
{
    
LogError("socket error %d (errno %d)"errorTypeerrorNum);
    
CloseHandle(socket);
}

//When the CLIENT connected to the server :
public OnClientSocketConnected(Handle socketany arg)
{
    
PrintToServer("Sucessfully connected to master chat server ! (%s:%i)""yourgameserver.com"2044);
    
    
//Nothing much to say...
}

//Client disconnected from the server
public OnChildSocketDisconnected(Handle socketany hFile)
{
    if(!
isMasterServer)
        
PrintToServer("Lost connection to master chat server !");
    
CloseHandle(socket);

But where is 'OnChildSocketReceive' ? Well, look back up, we alread spoke about it.

And that's it ! Your clients can communicate with your server and your server can communicate with your clients ! Now, we just need to see HOW you can communicate...

Sending messages

Step 1) And our last missing stock :

This one is very important, she allow you to send messages to all clients registred in connections array !
PHP Code:
//Stock to send a message to all clients :
stock void SendToAllClients(char[] finalMessageint msgSizeHandle sender)
{
    
//Loop through all clients :
    
for(int i 0GetArraySize(ARRAY_Connections); i++)
    {
        
//Get client :
        
Handle clientSocket GetArrayCell(ARRAY_Connectionsi);
        if(
clientSocket != sender)
        {
            
//If the handle to the client socket and the socket is connected, send the message :
            
if(clientSocket != INVALID_HANDLE && SocketIsConnected(clientSocket))
                
SocketSend(clientSocketfinalMessagemsgSize);
        }
    }

step 2) One little test command

I just added a RegServerCmd() to the OnPluginStart() function and the small callback :
PHP Code:
public void OnPluginStart()
{
    
CVAR_MasterChatServer CreateConVar("sm_csc_is_server""0""Is this server the server ? 1 = yes | 0 = no, it's a client"_true0.0true1.0);
    
    
ARRAY_Connections CreateArray(); // Init the array
    
    
RegConsoleCmd("sm_sendmsg"CMD_SendMessage"Send a message");
}

//And the call back
public Action CMD_SendMessage(clientargs)
{
    if(
isMasterServer)
        
SendToAllClients("test"7INVALID_HANDLE);    //If the game server is a server, create the server
    
else
        
SocketSend(clientHandle"test"7);

That's definitly it. You finish your base plugin, now you can add your features our do what ever you want.

Final plugin
At the end, you should have this :
Spoiler


The end.
Attached Thumbnails
Click image for larger version

Name:	test.png
Views:	1389
Size:	4.3 KB
ID:	147723   Click image for larger version

Name:	schema.png
Views:	1493
Size:	48.7 KB
ID:	147724  
__________________
Want to check my plugins ?

Last edited by Arkarr; 08-26-2015 at 07:50.
Arkarr is offline
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 08-26-2015 , 03:12   Re: [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #2

Just for me
__________________
Want to check my plugins ?
Arkarr is offline
Darkness_
Veteran Member
Join Date: Nov 2014
Old 08-26-2015 , 04:01   Re: [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #3

Thanks for this.
Darkness_ is offline
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 08-26-2015 , 04:07   Re: [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #4

Quote:
Originally Posted by Darkness_ View Post
Thanks for this.
Not finished D: !
Finished !

And no problem at all ! Have fun !
__________________
Want to check my plugins ?

Last edited by Arkarr; 08-26-2015 at 04:13.
Arkarr is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 08-26-2015 , 12:45   Re: [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #5

cool! did you figure out what was wrong with the thing you posted earlier, then?
Miu is offline
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 08-26-2015 , 13:04   Re: [ANY] Using Socket Extension to send paquets between servers !
Reply With Quote #6

Quote:
Originally Posted by Miu View Post
cool! did you figure out what was wrong with the thing you posted earlier, then?
Yep, definitly !
__________________
Want to check my plugins ?
Arkarr is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 14:50.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode