Keine Beschreibung
Datei suchen
2026-03-13 14:02:04 -03:00
knitpkg/include/douglasrechia/sockets Prints replaced with storing the last error message 2026-03-10 19:14:24 -03:00
tests Added README and Unit test 2026-03-13 14:02:04 -03:00
.gitignore Added README and Unit test 2026-03-13 14:02:04 -03:00
knitpkg.yaml Added README and Unit test 2026-03-13 14:02:04 -03:00
README.md Added README and Unit test 2026-03-13 14:02:04 -03:00

Package sockets

TCP socket communication library for MQL5 using Winsock2
MIT License


What is this?

sockets is a TCP socket communication library for MQL5 that wraps the Windows Winsock2 API.

It provides:

  • ClientSocket class for connecting to TCP servers
  • ServerSocket class for creating TCP servers
  • Non-blocking I/O operations
  • Message framing with customizable separators
  • Binary and text data transmission
  • Error handling without Print() calls
  • Automatic hostname resolution (DNS)
  • Support for both 32-bit and 64-bit MetaTrader 5

This package enables MQL5 programs to communicate over TCP/IP networks, making it possible to integrate Expert Advisors, Scripts, and Services with external applications, databases, and web services.

Prerequisites

To use this project, you will need:

  1. MetaTrader 5 installed.
  2. KnitPkg CLI: The KnitPkg package manager for MetaTrader. If you don't have it, you can install it by following the instructions in the main KnitPkg repository.
  3. KnitPkg homepage: See https://knitpkg.dev for an overview and https://docs.knitpkg.dev for documentation.

Features

  • Package type (type: package) — header-only library consumable by other KnitPkg projects
  • MQL5 target — designed for MetaTrader 5
  • Compile supportkp compile compiles the unit test script(s)
  • TCP client sockets — connect to remote servers from EAs and Scripts
  • TCP server sockets — create servers in MQL5 Services
  • Non-blocking I/O — all operations are non-blocking for responsive applications
  • Message framing — built-in support for message delimiters (e.g., newline)
  • Binary and text data — send/receive both string and binary data
  • Error handling — retrieve error messages via GetLastError() without Print() calls
  • DNS resolution — automatic hostname to IP address resolution
  • Cross-architecture — works on both 32-bit and 64-bit MT5 terminals

To add sockets to your KnitPkg project:

kp add @douglasrechia/sockets

Basic usage (example)

In the case your MQL5 project uses include_mode: include, include headers from the KnitPkg include directory:

#include "../knitpkg/include/douglasrechia/sockets/Sockets.mqh"

Client Socket Example

void OnStart()
{
   // Connect to server
   douglasrechia::ClientSocket* client = new douglasrechia::ClientSocket("127.0.0.1", 8080);
   
   if(!client.IsSocketConnected())
   {
      Print("Connection failed: ", client.GetLastError());
      delete client;
      return;
   }
   
   // Send a message
   if(!client.Send("Hello Server\n"))
   {
      Print("Send failed: ", client.GetLastError());
   }
   
   // Receive response (with newline separator)
   string response = "";
   while(response == "" && client.IsSocketConnected())
   {
      response = client.Receive("\n");
      Sleep(10);
   }
   
   Print("Server response: ", response);
   
   // Cleanup
   delete client;
}

Server Socket Example

douglasrechia::ServerSocket* server;
douglasrechia::ClientSocket* clients[];

void OnStart()
{
   // Create server on port 8080
   server = new douglasrechia::ServerSocket(8080);
   
   if(!server.Created())
   {
      Print("Server creation failed: ", server.GetLastError());
      return;
   }
   
   Print("Server listening on port 8080");
   
   // Main server loop
   while(!IsStopped())
   {
      // Accept new connections
      douglasrechia::ClientSocket* newClient = server.Accept();
      if(newClient != NULL)
      {
         Print("New client connected");
         int size = ArraySize(clients);
         ArrayResize(clients, size + 1);
         clients[size] = newClient;
      }
      
      // Process existing clients
      for(int i = ArraySize(clients) - 1; i >= 0; i--)
      {
         string msg = clients[i].Receive("\n");
         if(msg != "")
         {
            Print("Received: ", msg);
            // Echo back
            clients[i].Send("Echo: " + msg + "\n");
         }
         
         // Remove disconnected clients
         if(!clients[i].IsSocketConnected())
         {
            delete clients[i];
            ArrayRemove(clients, i, 1);
         }
      }
      
      Sleep(10);
   }
   
   // Cleanup
   for(int i = 0; i < ArraySize(clients); i++)
      delete clients[i];
   delete server;
}

Note: The exact method signatures and usage patterns are documented in the header files. Use MetaEditor IntelliSense to browse the available APIs.


Exploring the project locally (optional)

If you want to explore how a KnitPkg package is structured, clone the repository and run the standard workflow.

1) Clone into MetaTrader Scripts folder (example)

# Go to your MetaTrader 'Scripts' directory.
# Tip: in MetaEditor, right-click the `Scripts` folder and choose "Open Folder".
cd "C:\Users\username\AppData\Roaming\MetaQuotes\Terminal\<TERMINAL_ID>\MQL5\Scripts"

git clone https://forge.mql5.io/DouglasRechia/sockets.git
cd sockets

2) Compile

kp compile

Running unit tests

Unit tests are implemented as a MetaTrader Script.

  1. Compile the project.
  2. Restart MetaTrader (so the Navigator refreshes).
  3. Run the generated unit test script from the Navigator on any chart.
  4. Check results in the MetaTrader console (Experts/Scripts tab, depending on your setup).

The compiled binary is placed under the project bin/ directory (and appears in the Navigator under the corresponding compiled location after refresh).


One-command download/build via the registry (optional)

You can also use kp get to query the registry for metadata and automatically download/build the latest stable version.

Example (run from your MetaTrader Data Folder root):

cd "C:\Users\username\AppData\Roaming\MetaQuotes\Terminal\<TERMINAL_ID>"

kp get mql5 @douglasrechia/sockets

Restart MetaTrader afterward to refresh the Navigator, then run the unit test script as described above.


API Reference

ClientSocket

Constructor

ClientSocket(string serverHost, ushort serverPort)

Creates a client socket and connects to the specified server.

Methods

Method Description
bool IsSocketConnected() Returns true if socket is connected
string GetLastError() Returns the last error message
void ClearLastError() Clears the last error message
void CloseSocket() Closes the socket connection
bool Send(string strMsg) Sends a UTF-8 string
bool Send(uchar& buffer[], int startAt=0, int szToSend=-1) Sends binary data
string Receive(string MessageSeparator="") Receives string data with optional message separator
int Receive(uchar& buffer[]) Receives binary data, returns number of bytes

ServerSocket

Constructor

ServerSocket(ushort serverPort, bool reuse=true)

Creates a server socket listening on the specified port.

Methods

Method Description
bool Created() Returns true if server was created successfully
string GetLastError() Returns the last error message
void ClearLastError() Clears the last error message
void CloseServer() Closes the server socket
ClientSocket* Accept() Accepts a pending connection, returns NULL if none waiting

Message Framing

TCP is stream-oriented, not message-oriented. The MessageSeparator parameter solves the message framing problem:

// Without separator - returns all buffered data (may be incomplete)
string data = client.Receive("");

// With separator - returns only complete messages
string message = client.Receive("\n");  // Waits for newline

When using a separator:

  • Data accumulates in an internal buffer until the separator is found
  • Returns the first complete message (without the separator)
  • Remaining data stays buffered for the next call
  • Returns empty string if message is incomplete

Platform Support

  • Windows (32-bit and 64-bit MetaTrader 5)
  • Linux/macOS (Winsock2 is Windows-only)

License

This project is released under the MIT License. See LICENSE for details.


Disclaimer

This code is provided as-is, for educational purposes only.
No warranty (express or implied) is provided. Use at your own risk.