commit 87f1bca0d58641127132a5083f3e5285298d7e16 Author: 宇宙遨游 <2746069727@qq.com> Date: Thu Oct 26 09:08:46 2023 +0800 demo diff --git a/client.py b/client.py new file mode 100644 index 0000000..5f24bee --- /dev/null +++ b/client.py @@ -0,0 +1,49 @@ +import socket +from threading import Thread + +BUFFER_SIZE = 1024 +TIME_OUT = 5 + +p2p_serv_addr = (input('输入P2P服务器地址: '),9000) +def get_server_port(ip): + sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + sock.sendto(f'ip {ip}'.encode(),p2p_serv_addr) + buf,_ = sock.recvfrom(BUFFER_SIZE) + sock.close() + return int(buf.decode()) + +server_ip = input('输入服务器地址: ') +server_addr = (server_ip,get_server_port(server_ip)) + +tcp = socket.socket(socket.AF_INET,socket.SOCK_STREAM) +tcp.bind(('0.0.0.0',9001)) +tcp.listen() + +def get_server_data(tcp_sock,udp_sock): + try: + while True: + buf,_ = udp_sock.recvfrom(BUFFER_SIZE) + tcp_sock.send(buf) + except: + pass + +def client_handler(sock): + udp_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + udp_sock.sendto(b'hello',p2p_serv_addr) + Thread(target=get_server_data,args=[sock,udp_sock]).start() + try: + while True: + buf = sock.recv(BUFFER_SIZE) + if not buf: + break + udp_sock.sendto(buf,server_addr) + except: + pass + finally: + sock.close() + udp_sock.close() + +while True: + sock,_ = tcp.accept() + sock.settimeout(TIME_OUT) + Thread(target=client_handler,args=[sock]).start() diff --git a/p2p.png b/p2p.png new file mode 100644 index 0000000..0ea839f Binary files /dev/null and b/p2p.png differ diff --git a/p2pserve.py b/p2pserve.py new file mode 100644 index 0000000..501f06e --- /dev/null +++ b/p2pserve.py @@ -0,0 +1,40 @@ +import socket +from threading import Thread +from time import time,sleep + +BUFFER_SIZE = 1024 +udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) +udp.bind(('0.0.0.0',9000)) + +ip_map = {} + +def clean_ip_map(): + while True: + keys = ip_map.keys() + for v in keys: + if ip_map.get(v) == None: + continue + if (time() - ip_map[v]['time']) > 120: + ip_map[v] = None + sleep(5) + +Thread(target=clean_ip_map).start() + +def cache_address(addr): + ip_map[addr[0]] = {'port':addr[1],'time':int(time())} + +def get_address(data,addr): + if ip_map.get(data) == None: + return + udp.sendto(str(ip_map[data]['port']).encode(),addr) + +while True: + buf,addr = udp.recvfrom(BUFFER_SIZE) + try: + data = buf.decode() + if data[:4] == 'life': + cache_address(addr) + elif data[:2] == 'ip': + get_address(data[3:],addr) + except: + pass \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..8e1c299 --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# p2p 测试代码 +## 通过p2p方式无需服务器转发流量实现内网穿透 思路见 p2p.png +## 测试效果见 测试.png,udp to tcp协议转换代码可能不稳定 \ No newline at end of file diff --git a/serve.py b/serve.py new file mode 100644 index 0000000..85b7d5c --- /dev/null +++ b/serve.py @@ -0,0 +1,54 @@ +import socket +from time import sleep +from threading import Thread + +BUFFER_SIZE = 1024 +TIME_OUT = 5 + +game_serv_addr = ('127.0.0.1',int(input('输入游戏服务器端口: '))) +p2p_serv_addr = (input('输入P2P服务器地址: '),9000) +udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + +def life_data(): + while True: + udp.sendto('life'.encode(),p2p_serv_addr) + sleep(10) + +Thread(target=life_data).start() + +udp.sendto('life'.encode(),p2p_serv_addr) + + +client_map = {} + +def addr_to_ip(addr): + return f'{addr[0]}:{str(addr[1])}' + +def client_handler(sock,addr): + try: + while True: + buf = sock.recv(BUFFER_SIZE) + if not buf: + break + udp.sendto(buf,addr) + except: + pass + finally: + sock.close() + client_map[addr_to_ip(addr)] = None + +while True: + try: + buf,addr = udp.recvfrom(BUFFER_SIZE) + ip = addr_to_ip(addr) + if client_map.get(ip) == None: + sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + sock.settimeout(TIME_OUT) + sock.connect(game_serv_addr) + Thread(target=client_handler,args=[sock,addr]).start() + client_map[ip] = sock + + client = client_map[ip] + client.send(buf) + except: + pass diff --git a/test.bat b/test.bat new file mode 100644 index 0000000..7fca7ae --- /dev/null +++ b/test.bat @@ -0,0 +1,5 @@ +start python p2pserve.py +timeout /t 1 +start python serve.py +timeout /t 1 +start python client.py \ No newline at end of file diff --git a/测试.png b/测试.png new file mode 100644 index 0000000..774a8ec Binary files /dev/null and b/测试.png differ