Skip to main content

simple_tcp_server

Simple TCP server framework.

Installation

pip install simple_tcp_server

Usage

from simple_tcp_server import SimpleTcpServer, SimpleTcpClient
import threading
import time

HOST = "127.0.0.1"
PORT = 9999

def is_prime(msg: bytes) -> bytes:
    n = int(msg.decode())
    if n < 2:
        return b"not prime"
    for i in range(2, int(n**0.5)+1):
        if n % i == 0:
            return b"not prime"
    return b"prime"

server = SimpleTcpServer(HOST, PORT, is_prime, quit_token=b"quit")
server.set_debug_mode(True) # default is False
t = threading.Thread(target=server.mainloop, daemon=True)
t.start()

time.sleep(0.2)

client = SimpleTcpClient(HOST, PORT)

numbers = [b"2", b"10", b"17", b"97", b"1234567"]
for n in numbers:
    res = client.request(n)

# close server by quit_token
client.request(b"quit")
for n in numbers:
    res = client.request(n)

client.close()

Message framing

When a client connects, it sends one strategy byte to negotiate message framing for that connection. The server stores the negotiated strategy per client and responds to each client with the same framing. SimpleTcpServer does not need a framing option.

SimpleTcpClient uses framing_strategy="E" by default. Choose a mode when creating the client:

legacy_client = SimpleTcpClient(HOST, PORT)
l_client = SimpleTcpClient(HOST, PORT, framing_strategy="L")
d_client = SimpleTcpClient(HOST, PORT, framing_strategy="D")

Negotiation byte

The first byte sent by a new client chooses the framing strategy:

Byte Strategy Meaning
b"E" E mode End-marker framing, compatible with the original protocol.
b"L" L mode 4-byte length-prefix framing.
b"D" D mode 8-byte length-prefix framing.

If the first byte is not b"E", b"L", or b"D", the server defaults that client to E mode and keeps the byte as part of the first message. This keeps clients that do not send a negotiation byte compatible with the default protocol.

E Mode

E mode is the original end-marker protocol. Each message is sent as:

escaped payload + b"$$"

Because b"$$" marks the end of a message, every b"$" byte inside the payload is escaped before sending and unescaped after receiving. This mode is the default and is useful for compatibility with existing clients.

Example payload:

client = SimpleTcpClient(HOST, PORT)  # same as framing_strategy="E"
res = client.request(b"value with $ and $$")

L Mode

L mode uses a 4-byte unsigned big-endian integer before every payload:

4-byte payload length + raw payload

The length describes only the payload after the 4-byte prefix. The prefix allows the receiver to know exactly how many bytes belong to the message, so the payload is not escaped. This mode is binary-safe: payloads may contain b"$", b"$$", null bytes, or any other byte value.

Example payload:

client = SimpleTcpClient(HOST, PORT, framing_strategy="L")
res = client.request(b"value with $$ and \x00 bytes")

D Mode

D mode is the same idea as L mode, but the length field is 8 bytes:

8-byte payload length + raw payload

The 8-byte length is an unsigned big-endian integer and describes only the payload after the prefix. Like L mode, D mode does not escape the payload and is binary-safe. Use D mode when you want the protocol shape to allow payloads larger than the 4-byte L-mode limit.

Example payload:

client = SimpleTcpClient(HOST, PORT, framing_strategy="D")
res = client.request(b"large or binary payload")

Metadata

Release files for simple-tcp-server 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for simple-tcp-server 0.1.3
File Size Uploaded
simple_tcp_server-0.1.3.tar.gz 6.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for simple-tcp-server 0.1.3
File Interpreter ABI Platform
simple_tcp_server-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 15.2 kB

Release files / simple_tcp_server-0.1.3.tar.gz

Download URL simple_tcp_server-0.1.3.tar.gz
Size 6.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c64e07188a2b95cb570e5479a04a21b02fb0f0b022d36bf84f7d845a4ff9794c
BLAKE2b-256 checksum
How to use checksums
f08e12deb7a241890b0727ca2c512853360772707b3e7e379c44de9a0a20396f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.11.15 Windows/10

Release files / simple_tcp_server-0.1.3-py3-none-any.whl

Download URL simple_tcp_server-0.1.3-py3-none-any.whl
Size 8.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4ececb7a45a9ce9a89d91b71b5e3f389a914b864860e3fd06753af9e514c3e9
BLAKE2b-256 checksum
How to use checksums
6f9a2d3c3929b3528c6fda526512b5fc0edcff7ebb3e59209b9bd8c600682e71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.11.15 Windows/10

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page