#!/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)