57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
# PC-side control experiment (no device involved; lives in MDK-ARM/bench_diag/).
|
|
# Question: is "sendall(4096) then close()" against a SLOW receiver (small SO_RCVBUF,
|
|
# no prompt read) lossless on a normal TCP stack? If yes here but lossy against the
|
|
# device, the loss is device-side; if lossy here too, it is generic TCP/client behaviour.
|
|
import socket, sys, threading, time
|
|
|
|
def log(m):
|
|
sys.stdout.write(m + "\n"); sys.stdout.flush()
|
|
|
|
def run(rcvbuf, read_delay, send_size=4096):
|
|
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
srv.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, rcvbuf)
|
|
srv.bind(("127.0.0.1", 0))
|
|
srv.listen(1)
|
|
port = srv.getsockname()[1]
|
|
got = bytearray()
|
|
res = {}
|
|
|
|
def server():
|
|
c, _ = srv.accept()
|
|
if read_delay:
|
|
time.sleep(read_delay) # receiver does not read promptly
|
|
c.settimeout(3.0)
|
|
try:
|
|
while True:
|
|
b = c.recv(65536)
|
|
if not b:
|
|
break
|
|
got.extend(b)
|
|
except Exception as e:
|
|
res["err"] = repr(e)
|
|
res["n"] = len(got)
|
|
c.close()
|
|
|
|
t = threading.Thread(target=server, daemon=True)
|
|
t.start()
|
|
time.sleep(0.15)
|
|
cli = socket.create_connection(("127.0.0.1", port), timeout=5.0)
|
|
cli.sendall(bytes([(i * 13 + 5) & 0xFF for i in range(send_size)]))
|
|
cli.close() # close immediately after sendall
|
|
t.join(timeout=8)
|
|
srv.close()
|
|
ok = res.get("n") == send_size
|
|
log(" PC-control rcvbuf=%-6d read_delay=%-4s sent=%d received=%s %s %s"
|
|
% (rcvbuf, read_delay, send_size, res.get("n"),
|
|
"OK" if ok else "LOSS", res.get("err", "")))
|
|
return res.get("n")
|
|
|
|
log("=== PC-side reference (loopback): does an immediate close() lose data when the")
|
|
log("=== receiver reads late / has a tiny buffer? Expected on a correct stack: no loss.")
|
|
run(2048, 0.0)
|
|
run(2048, 1.5)
|
|
run(65536, 0.0)
|
|
run(65536, 1.5)
|