Clausal — TCP Module (tcp)¶
Overview¶
The tcp module provides predicates for TCP client/server socket operations,
wrapping Python's socket module. Socket handles are opaque Python objects —
use them with Send, Receive, and Close.
-import_from(py.tcp, [Connect, Send, Receive, Close])
EchoClient(HOST, PORT, MESSAGE, RESPONSE) <- (
Connect(HOST, PORT, SOCKET),
Send(SOCKET, MESSAGE),
Receive(SOCKET, RESPONSE),
Close(SOCKET)
)
Or via module import:
-import_module(py.tcp)
Main <- (
py.tcp.Connect("localhost", 8080, S),
py.tcp.Send(S, "hello"),
py.tcp.Receive(S, REPLY),
++print(REPLY),
py.tcp.Close(S)
)
Import¶
Client predicates¶
| Predicate | Mode | Description |
|---|---|---|
Connect(Host, Port, Socket) |
+Host, +Port, -Socket |
Connect to TCP server, bind opaque socket handle |
Fails if the connection is refused or the host is unreachable.
Server predicates¶
| Predicate | Mode | Description |
|---|---|---|
Listen(Host, Port, ServerSocket) |
+Host, +Port, -ServerSocket |
Create listening socket with SO_REUSEADDR. Port 0 → ephemeral. |
Accept(ServerSocket, ClientSocket) |
+Server, -Client |
Accept incoming connection. Blocks until a client connects. |
Listen("0.0.0.0", 8080, SERVER),
Accept(SERVER, CLIENT),
Receive(CLIENT, DATA),
Send(CLIENT, DATA), # echo back
Close(CLIENT),
Close(SERVER)
Data transfer¶
| Predicate | Mode | Description |
|---|---|---|
Send(Socket, Data) |
+Socket, +Data |
Send string (UTF-8) or bytes via sendall() |
Receive(Socket, Data) |
+Socket, -Data |
Receive up to 4096 bytes, decode UTF-8 |
Receive(Socket, BufferSize, Data) |
+Socket, +BufSize, -Data |
Receive with custom buffer size |
Receive returns a string if the data is valid UTF-8, or raw bytes if
decoding fails. Fails if the connection is closed (no data received).
Send(SOCKET, "Hello, server!")
Receive(SOCKET, RESPONSE)
# Custom buffer size
Receive(SOCKET, 65536, LARGE_DATA)
Socket management¶
| Predicate | Mode | Description |
|---|---|---|
Close(Socket) |
+Socket |
Close socket. Always succeeds (even on already-closed sockets). |
SetTimeout(Socket, Seconds) |
+Socket, +Seconds |
Set socket timeout (float). Subsequent operations fail on timeout. |
SetTimeout(SOCKET, 5.0), # 5-second timeout
Receive(SOCKET, DATA) # fails if no data within 5 seconds
Examples
Simple TCP client¶
-import_from(py.tcp, [Connect, Send, Receive, Close])
TcpRequest(HOST, PORT, REQUEST, RESPONSE) <- (
Connect(HOST, PORT, S),
Send(S, REQUEST),
Receive(S, RESPONSE),
Close(S)
)
Echo server (single client)¶
Gotchas¶
- Sockets are impure — socket operations have side effects and do not
backtrack cleanly. If a
Sendsucceeds but a later goal fails, the data has already been sent. Acceptblocks — it waits for a connection. UseSetTimeouton the server socket to limit the wait time.- No automatic cleanup — always
Closesockets explicitly. Python's garbage collector will eventually close them, but relying on GC is bad practice for network resources. - Port 0 in
Listenlets the OS pick an ephemeral port — useful for tests.
See also: HTTP — higher-level HTTP requests (no sockets needed) ·
Process — shell commands and subprocess execution ·
Python Interop — ++() for advanced socket operations.