Sockets Support Package
Socket (raw socket) is an interface for exchanging data between processes both inside the same computer and between different machines over the network.
In the context of Engee, the raw socket runs on the side of the user’s client program through the Engee subsystem.Integration, and in Engee itself you get the results of data processing with the client program or send data to the client program unilaterally/bilaterally.
| To get started with the socket support package, install the Engee subsystem.Integration: Run the client program and specify the Engee server URL (see instructions). |
Basic methods
The key methods are listed below:
-
Sockets.Socket(family="AF_INET", socket_type="SOCK_STREAM", socket_descriptor=0)— constructor (TCP/IPv4 by default). -
Sockets.bind(device, host::String, port::Int64)— binding to the address/port. -
Sockets.listen(device, backlog::Int64)— Listening mode for incoming connections (for servers). -
Sockets.accept(device) → Int64— waits for the client, returns a descriptor[1] of the new socket. -
Sockets.connect(device, host::String, port::Int64) → Int64— Connect to a remote server (for clients). -
Sockets.send(device, message::Vector{UInt8})— sending bytes. -
Sockets.receive(device, bufsize::Int64) → Union{Nothing, ResultUIntList}— Reading in blocking mode. -
Sockets.is_open(device, socket_descriptor::Int64) → Bool— checking whether the socket is open. -
Sockets.close(device)— closing the socket and releasing resources.
Step-by-step example of working with Sockets
Consider an example of data exchange between two UDP sockets on the same computer (localhost). In this example:
-
Socket 1 acts as a server: it binds to a specific port and waits for data;
-
Socket 2 acts as a client: it connects to the port of socket 1 and sends messages.
-
Creation of the first socket (server) — create a socket by specifying the address family
AF_INET(IPv4) and typeSOCK_DGRAM(UDP):socket_1 = SOCKET.Socket("AF_INET", "SOCK_DGRAM") -
Bind the first socket to the address and port — bind the socket to the address of the local machine (
127.0.0.1) and the port8888. Now the socket "listens" to this port:socket_1.bind("127.0.0.1", 8888) -
Creating a second socket (client) — create a second socket with the same parameters:
socket_2 = SOCKET.Socket("AF_INET", "SOCK_DGRAM") -
Connecting the second socket to the server — connect the client socket to the address and port on which the server socket is "listening":
socket_2.connect("127.0.0.1", 8888) -
Message sending and verification cycle — Send 1000 messages from the second socket and immediately accept them in socket one, checking the correctness of delivery:
const num_messages = 1000 for i in 1:num_messages # Forming a text message message = "Message $i" # Convert the message to an array of bytes byte_array = collect(codeunits(message)) # Sending an array of bytes via socket 2 socket_2.send(byte_array) # We accept data (maximum 1000 bytes) on socket 1 res_for_recv = socket_1.receive(1000).data # We check that the received data matches the sent data. @assert res_for_recv == byte_array endType SOCK_DGRAM(UDP) does not guarantee the delivery and order of packets, but within the same computer (localhost), data exchange is almost lossless, which makes the example stable. -
Closing sockets and freeing resources — after the exchange is complete, close both sockets:
socket_1.close() socket_2.close()
-