I'm implementing a socket server for python. Ideally I would use a socketserver.TCPServer
in combination with thereadline
-functionality of socketserver.StreamRequestHandler
, see for instance the example in the documentation. Unfortunaltely I have to use a custom newline character other than \n
.
Is there a way to change this newline character in this context? Accoding to my debugger the rfile
-attribute of socketserver.StreamRequestHandler,
is a _io.BufferedReader
-object but I couldn't find any documentation about that.
No, there is not a way to change the newline character. rfile
is an io.BufferedReader
which is a buffered binary stream which inherits the readline()
method from io.IOBase
(emphasis mine)
readline(size=-1, /)
Read and return one line from the stream. If size is specified, at most size bytes will be read.The line terminator is always
b'\n'
for binary files; for text files, the newline argument to open() can be used to select the line terminator(s) recognized.
You can buffer your own fixed reads and extract messages using your own newline character(s) with code like the following:
import socketserver as ss
import threading
import socket
class MyTCPHandler(ss.StreamRequestHandler):
_buffer = b''
LINEEND = b'xy'
def handle(self):
while True:
line = self.read_until(self.LINEEND)
if not line: break
print(line)
def read_until(self, terminator):
while terminator not in self._buffer:
chunk = self.request.recv(1024)
if not chunk: break
self._buffer += chunk
msg, _, self._buffer = self._buffer.partition(terminator)
return msg
def server():
with ss.ThreadingTCPServer(('', 5000), MyTCPHandler) as server:
server.serve_forever()
threading.Thread(target=server, daemon=True).start()
# client 1
with socket.socket() as client1, socket.socket() as client2:
client1.connect(('localhost', 5000))
client2.connect(('localhost', 5000))
client1.sendall(b'client 1 message 1xyclient 1')
client2.sendall(b'client 2 message 1xyclient 2')
client1.sendall(b' message 2xyclient 1 message 3xy')
client2.sendall(b' message 2xyclient 2 message 3xy')
Output:
b'client 1 message 1'
b'client 2 message 1'
b'client 1 message 2'
b'client 2 message 2'
b'client 1 message 3'
b'client 2 message 3'