| knitpkg/include/douglasrechia/sockets | ||
| tests | ||
| .gitignore | ||
| knitpkg.yaml | ||
| README.md | ||
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:
ClientSocketclass for connecting to TCP serversServerSocketclass 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:
- MetaTrader 5 installed.
- 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.
- 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 support —
kp compilecompiles 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
Installing as a dependency (recommended)
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.
- Compile the project.
- Restart MetaTrader (so the Navigator refreshes).
- Run the generated unit test script from the Navigator on any chart.
- 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.