あなたの編集は、あなたが望むのはあなたの目標を達成するための組み込みのアプローチであることを明確にしていることを理解しています. しかし、readline アプローチをきめ細かく制御するのに役立つものが存在することを私は知りません。しかし、ジェネレーターと分割を使用してコード化されたアプローチを行う例を含めるだけでよいと思いました...ただの楽しみです。
行を読み取る素敵なジェネレーターについては、この他の質問/回答を参照してください:
https://stackoverflow.com/a/822788/496445
その読者に基づいて:
サーバー.py
import socket
MAXLINE = 100
def linesplit(sock, maxline=0):
buf = sock.recv(16)
done = False
while not done:
# mid line check
if maxline and len(buf) > maxline:
yield buf, True
if "\n" in buf:
(line, buf) = buf.split("\n", 1)
err = maxline and len(line) > maxline
yield line+"\n", err
else:
more = sock.recv(16)
if not more:
done = True
else:
buf = buf+more
if buf:
err = maxline and len(buf) > maxline
yield buf, err
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
for line, err in linesplit(conn, MAXLINE):
if err:
print "Error: Line greater than allowed length %d (got %d)" \
% (MAXLINE, len(line))
break
else:
print "Received data:", line.strip()
conn.close()
client.py
import socket
import time
import random
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
val = 'x'*random.randint(1, 50)
if random.random() > .5:
val += "\n"
s.sendall(val)
time.sleep(.1)
s.close()
出力
Connected by ('127.0.0.1', 57912)
Received data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Received data: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Received data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
Received data: xxxxxxxxxxx
Received data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Error: Line greater than allowed length 100 (got 102)
サーバーは、受信したデータを読み取り、ラインを組み立てると、ラインの長さを常にチェックします。行が指定された金額を超えると、いつでもエラー コードが返されます。これをすばやくまとめたので、チェックをもう少しクリーンアップできると確信しています。また、読み取りバッファーの量を変更して、大量のデータを消費する前に長い行を検出する速度に対処できます。上記の出力例では、許可されているよりも 2 バイト多いだけで、停止しました。
クライアントはランダムな長さのデータを送信し、改行を 50/50 に変更します。