import threading import uuid from utils import * client_token = f"client_{uuid.uuid4().hex[:8]}" my_charactor = "client" client_name = 'awin_client' server_name = 'awin_server' service_name = 'alist' co_server = 'www.awin-x.top' co_port = 5000 co_server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) co_server_sock.connect((co_server, co_port)) listen_port = 12345 listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_sock.bind(('0.0.0.0', listen_port)) listen_sock.listen(5) udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_sock.bind(('0.0.0.0', 0)) tcp_port = udp_sock.getsockname()[1] server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) conns = {} def client_thread(conn_id): client_sock = conns[conn_id]['client_sock'] while True: data = client_sock.recv(4096) send_data_tcp(server_sock, data, {'conn_id': conn_id}) def tcp_accept_thread(): while True: client_sock, client_addr = listen_sock.accept() conn_id = f"conn_{uuid.uuid4().hex[:8]}" conns[conn_id] = { 'client_sock': client_sock, 'client_addr': client_addr, 'ready': False } send_action_tcp(server_sock, 'connect_service', { 'service': service_name, 'conn_id': conn_id, 'client_addr': client_addr, 'client_name': client_name }) count = 0 while not conns[conn_id]['ready']: if count > 50: send_action_tcp(server_sock, 'disconnect_service', { 'conn_id': conn_id }) break time.sleep(0.1) threading.Thread(target=client_thread, args=conn_id).start() def handle_data(conn_id, data): conns[conn_id]['client_sock'].sendall(data) def server_thread(): global client_name, client_token send_action_tcp(server_sock, 'client_hello', { 'client_name': client_name, 'client_token': client_token }) while True: action, message, data = recv_tcp(server_sock) if action == 'error': print(message['message']) elif action == 'data': handle_data(message['conn_id'], data) elif action == 'bye': break server_sock.close() print("bye, from server") exit() def main(): send_action_tcp(co_server_sock, 'client_hello', { 'name': client_name, 'token': client_token, 'charactor': my_charactor, }) send_action_tcp(co_server_sock, 'punch_request', { 'server_name': 'awin_server' }) action, message, data = recv_tcp(co_server_sock) if action == 'punch_request': co_server_punch_port = message['co_server_punch_port'] else: print('punch request failed') return print(f'暴露端口:{tcp_port}->{(co_server, co_server_punch_port)}') packed = pack_data(action='client_punch_port') for i in range(5): udp_sock.sendto(packed, (co_server, co_server_punch_port)) time.sleep(0.1) action, message, data = recv_tcp(co_server_sock) if action == 'punch_to': target_addr = tuple(message['target_addr']) print(f'打洞到{target_addr}') udp_sock.close() server_sock.bind(('0.0.0.0', tcp_port)) server_sock.connect(target_addr) threading.Thread(target=server_thread, daemon=True).start() else: print(action) print('punch to failed') return if __name__ == '__main__': main()