Search Results for

    Show / Hide Table of Contents

    HOWTO: Create TCP client-server

    The following example uses a pair of Server and Client scripts to send a text message over the network. Note that this example uses non-blocking code and performs pooling on sockets during script OnUpdate.

    To use it simple create a pair of scripts and add them to the scene.

    C#

    Client

    using System.Text;
    using FlaxEngine;
    
    public class CSharpClient : Script
    {
        private NetworkSocket _socket;
        private byte[] _buffer = new byte[100];
    
        /// <inheritdoc/>
        public override void OnEnable()
        {
            Debug.Log("Setting up client");
            Network.CreateEndPoint("localhost", "35000", NetworkIPVersion.IPv4, out var endPoint);
            Network.CreateSocket(ref _socket, NetworkProtocol.Tcp, NetworkIPVersion.IPv4);
            Network.SetSocketOption(ref _socket, NetworkSocketOption.ReuseAddr, 1);
            Network.ConnectSocket(ref _socket, ref endPoint);
            Debug.Log("Client listening for server...");
        }
    
        /// <inheritdoc/>
        public override void OnDisable()
        {
            Network.DestroySocket(ref _socket);
        }
    
        /// <inheritdoc/>
        public override void OnUpdate()
        {
            if (Network.IsReadable(ref _socket))
            {
                int size = Network.ReadSocket(_socket, _buffer);
                if (size > 0)
                {
                    _buffer[size] = 0;
                    Debug.Log($"Message : {Encoding.ASCII.GetString(_buffer)} | Size : {size}");
                }
            }
        }
    }
    

    Server

    using System.Text;
    using FlaxEngine;
    
    public class CSharpServer : Script
    {
        private bool _connected;
        private NetworkSocket _serverSocket;
        private NetworkSocket _clientSocket;
    
        /// <inheritdoc/>
        public override void OnEnable()
        {
            Debug.Log("Setting up server");
            Network.CreateEndPoint(null, "35000", NetworkIPVersion.IPv4, out var serverPoint);
            Network.CreateSocket(ref _serverSocket, NetworkProtocol.Tcp, NetworkIPVersion.IPv4);
            Network.SetSocketOption(ref _serverSocket, NetworkSocketOption.ReuseAddr, 1);
            Network.BindSocket(ref _serverSocket, ref serverPoint);
            Network.Listen(ref _serverSocket, 100);
            Debug.Log("Server waiting for connection...");
        }
    
        /// <inheritdoc/>
        public override void OnDisable()
        {
            Debug.Log("Shutting down server");
            if (_connected)
            {
                Network.DestroySocket(ref _clientSocket);
                _connected = false;
            }
    
            Network.DestroySocket(ref _serverSocket);
        }
    
        /// <inheritdoc/>
        public override void OnUpdate()
        {
            if (Network.IsReadable(ref _serverSocket))
            {
                Network.Accept(ref _serverSocket, ref _clientSocket, out var clientPoint);
                Debug.Log("Client connected");
                _connected = true;
            }
    
            if (_connected && Network.IsWritable(ref _clientSocket))
            {
                string data = "Hello, world! The very first message.";
                int written = Network.WriteSocket(_clientSocket, Encoding.ASCII.GetBytes(data));
                Debug.Log($"Sended : {written}");
                Network.DestroySocket(ref _clientSocket);
                _connected = false;
            }
        }
    }
    

    C++

    Client

    #pragma once
    
    #include "Engine/Scripting/Script.h"
    #include "Engine/Platform/Network.h"
    
    API_CLASS() class GAME_API CppClient : public Script
    {
    API_AUTO_SERIALIZATION();
    DECLARE_SCRIPTING_TYPE(CppClient);
    private:
        NetworkSocket _socket;
    
    public:
    
        // [Script]
        void OnEnable() override;
        void OnDisable() override;
        void OnUpdate() override;
    };
    
    #include "CppClient.h"
    #include "Engine/Core/Log.h"
    
    CppClient::CppClient(const SpawnParams& params)
        : Script(params)
    {
        _tickUpdate = true;
    }
    
    void CppClient::OnEnable()
    {
        LOG(Info, "Setting up client");
        NetworkEndPoint endPoint;
        Network::CreateEndPoint(TEXT("localhost"), TEXT("35000"), NetworkIPVersion::IPv4, endPoint);
        Network::CreateSocket(_socket, NetworkProtocol::Tcp, NetworkIPVersion::IPv4);
        Network::SetSocketOption(_socket, NetworkSocketOption::ReuseAddr, 1);
        Network::ConnectSocket(_socket, endPoint);
        LOG(Info, "Client listening for server...");
    }
    
    void CppClient::OnDisable()
    {
        Network::DestroySocket(_socket);
    }
    
    void CppClient::OnUpdate()
    {
        if (Network::IsReadable(_socket))
        {
            byte buf[100];
            const int32 size = Network::ReadSocket(_socket, buf, ARRAY_COUNT(buf) - 1);
            if (size > 0)
            {
                buf[size] = '\0';
                LOG(Info, "Message : {0} | Size : {1}", String((char*)buf), size);
            }
        }
    }
    

    Server

    #pragma once
    
    #include "Engine/Scripting/Script.h"
    #include "Engine/Platform/Network.h"
    
    API_CLASS() class GAME_API CppServer : public Script
    {
    API_AUTO_SERIALIZATION();
    DECLARE_SCRIPTING_TYPE(CppServer);
    private:
        bool _connected;
        NetworkSocket _serverSocket;
        NetworkSocket _clientSocket;
    
    public:
    
        // [Script]
        void OnEnable() override;
        void OnDisable() override;
        void OnUpdate() override;
    };
    
    #include "CppServer.h"
    #include "Engine/Core/Log.h"
    
    CppServer::CppServer(const SpawnParams& params)
        : Script(params)
    {
        _tickUpdate = true;
    }
    
    void CppServer::OnEnable()
    {
        LOG(Info, "Setting up server");
        NetworkEndPoint serverPoint;
        Network::CreateEndPoint(String::Empty, TEXT("35000"), NetworkIPVersion::IPv4, serverPoint);
        Network::CreateSocket(_serverSocket, NetworkProtocol::Tcp, NetworkIPVersion::IPv4);
        Network::SetSocketOption(_serverSocket, NetworkSocketOption::ReuseAddr, 1);
        Network::BindSocket(_serverSocket, serverPoint);
        Network::Listen(_serverSocket, 100);
        LOG(Info, "Server waiting for connection...");
    }
    
    void CppServer::OnDisable()
    {
        LOG(Info, "Shutting down server");
        if (_connected)
        {
            Network::DestroySocket(_clientSocket);
            _connected = false;
        }
        Network::DestroySocket(_serverSocket);
    }
    
    void CppServer::OnUpdate()
    {
        if (Network::IsReadable(_serverSocket))
        {
            NetworkEndPoint clientPoint;
            Network::Accept(_serverSocket, _clientSocket, clientPoint);
            LOG(Info, "Client connected");
            _connected = true;
        }
    
        if (_connected && Network::IsWritable(_clientSocket))
        {
            const StringAnsi data("Hello, world! The very first message.");
            const int32 written = Network::WriteSocket(_clientSocket, (byte*)*data, data.Length());
            LOG(Info, "Sended : {0}", written);
            Network::DestroySocket(_clientSocket);
            _connected = false;
        }
    }
    
    • Improve this Doc
    In This Article
    Back to top Copyright © 2012-2024 Wojciech Figat