You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

76 lines
1.8 KiB

#!/usr/bin/env python3
"""TCP echo server for tcp_proxy integration test.
Accepts connections, reads all data, sends back.
Supports --read-timeout to close after idle (for half-close tests).
"""
import socket
import sys
import threading
import signal
running = True
def handle(conn: socket.socket, read_timeout: float):
try:
while True:
if read_timeout > 0:
conn.settimeout(read_timeout)
try:
data = conn.recv(65536)
except socket.timeout:
break
if not data:
break
conn.sendall(data)
except OSError:
pass
finally:
conn.close()
def main():
if len(sys.argv) < 3:
print(f"Usage: {sys.argv[0]} <host> <port> [--read-timeout SEC]", file=sys.stderr)
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
read_timeout = 0.0
for i in range(3, len(sys.argv)):
if sys.argv[i] == "--read-timeout" and i + 1 < len(sys.argv):
read_timeout = float(sys.argv[i + 1])
global running
def _sigterm(sig, frame):
global running
running = False
signal.signal(signal.SIGTERM, _sigterm)
signal.signal(signal.SIGINT, _sigterm)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(128)
print(f"ECHO: listening on {host}:{port}" + (f" timeout={read_timeout}s" if read_timeout > 0 else ""), flush=True)
while running:
try:
s.settimeout(1.0)
conn, addr = s.accept()
except socket.timeout:
continue
except OSError:
break
t = threading.Thread(target=handle, args=(conn, read_timeout), daemon=True)
t.start()
s.close()
if __name__ == "__main__":
main()