Product
Introducing License Enforcement in Socket
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Sends/receives messages in the following format:
| 1 byte | 8 bytes | ... |
| is compressed? | content length | data |
Messages over 575 bytes are automatically compressed/decompressed with zlib
The main classes are TcpServer and TcpClient, which use the above message format to communicate with each other.
TCP response messages are implemented in TcpMessages.
TcpMessage
has one member, content
, which is the bytes
content of the message
that will be sent. It also includes convenience methods for writing that content
to and from a TCP socket using the above format.
TcpServer
opens a connection when a request comes in, then listens on that
connection until either the client closes the connection or timeout
seconds,
passed to the constructor, have elapsed. The default is 30. This allows multiple
messages to be sent without re-creating new connections.
TCP request messages are implemented using TcpRequests,
which inherit from TcpMessage
. TcpRequests
include an additional member,
client_addr
, the requester's address.
When a request comes in, TcpServer
creates a TcpRequest
object with the
client's address and content of the incoming message, along with an empty TcpMessage
response. These objects are passed to a list of request handlers attached
to the server. After all handlers have run, TcpServer
sends the TcpMessage
response object to the client.
This allows the server to implement a Chain of Responsibility similar to Express/NodeJS. By passing objects to the various handlers, requests and responses can be modified by each method in the chain.
Example:
import time
from pytcp_message import TcpServer, TcpClient
from datetime import datetime
ADDR = "127.0.0.1"
PORT = 8080
def log_request(req, _):
now = datetime.now().strftime("%F %T")
print(
"[{}] {} <-- {}".format(
now,
req.get_client_address()[0],
req.get_content().decode("utf-8")
)
)
def send_response(req, res):
res.set_content("You are {}:{}".format(
*req.get_client_address()
).encode("utf-8"))
def log_response(req, res):
now = datetime.now().strftime("%F %T")
print("[{}] {} --> {}".format(
now,
res.get_content().decode("utf-8"),
req.get_client_address()[0]
))
def main():
send_message = "Hello{}"
tcpd = TcpServer(address=ADDR, port=PORT, timeout=5)
tcpd.add_request_handler(log_request)
tcpd.add_request_handler(send_response)
tcpd.add_request_handler(log_response)
tcpd.start()
print("Server running on tcp://{}:{}...".format(ADDR, PORT))
tcpc = TcpClient((ADDR, PORT))
for i in range(0, 10):
print("Client sending '{}'...".format(send_message.format(i)))
tcpc.send(send_message.format(i).encode("utf-8"))
response = tcpc.receive()
print("Client Received: '{}'\n".format(response.decode("utf-8")))
tcpc.stop()
print("Client closed connection.")
tcpd.stop()
time.sleep(5)
print("Server stopped.\n")
if __name__ == "__main__":
main()
Output:
Server running on tcp://127.0.0.1:8080...
Client sending 'Hello0'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello0
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello1'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello1
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello2'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello2
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello3'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello3
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello4'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello4
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello5'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello5
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello6'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello6
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello7'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello7
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello8'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello8
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client sending 'Hello9'...
[2020-06-19 21:01:28] 127.0.0.1 <-- Hello9
[2020-06-19 21:01:28] You are 127.0.0.1:34360 --> 127.0.0.1
Client Received: 'You are 127.0.0.1:34360'
Client closed connection.
Server stopped.
FAQs
Client and server for TCP message passing
We found that pytcp-message demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.
Product
We're excited to introduce Socket Optimize, a powerful CLI command to secure open source dependencies with tested, optimized package overrides.