AwinSimpleP2P/client.py
2025-06-08 20:17:59 +08:00

126 lines
3.5 KiB
Python

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()