import json import socket def is_cone_napt(dest1, dest2, timeout=2): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(timeout) sock.bind(("", 0)) try: sock.sendto("judge_napt_type", dest1) data1, _ = sock.recvfrom(1024) sock.sendto("judge_napt_type", dest2) data2, _ = sock.recvfrom(1024) ip1, port1 = data1.split(":") ip2, port2 = data2.split(":") return ip1 == ip2 and int(port1) == int(port2) finally: sock.close() def main(): Server1 = "timd.cn", 8082 Server2 = "timd.cn", 8083 P2P_Server = "timd.cn", 8081 MYNAME = "ClientB" can_make_hole = is_cone_napt(Server1, Server2) if not can_make_hole: raise RuntimeError("can't make hole") sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: sock.sendto(json.dumps({"op": "register", "name": MYNAME}), P2P_Server) data, _ = sock.recvfrom(1024) result = json.loads(data) if result["code"] != 0: raise RuntimeError("register failed") count = 1 while True: data, addr = sock.recvfrom(1024) request = json.loads(data) op = request["op"] if op == "prepare": peer = tuple(request["peer"]) sock.sendto(json.dumps({"op": "make_hole_for_you"}), peer) sock.sendto(json.dumps({"op": "prepare_ok", "peer": peer}), P2P_Server) elif op == "get_data": print("%s:%d is getting data" % addr) sock.sendto(json.dumps({"code": 0, "data": "%d. data from %s" % (count, MYNAME)}), addr) count = count + 1 finally: sock.close() if __name__ == "__main__": main()