udp穿透的方法
服务端缓存客户端ip+端口信息,如果有新的客户端连接上来返回给对方。
server
import socketdef main():udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)udp_socket.bind(("0.0.0.0", 2023))cache = {}while True:packet = udp_socket.recvfrom(2048)current = packet[1]key = packet[0].decode("utf-8")print("recvfrom key:", key)if key not in cache:cache[key] = packet[1]print("pending:", current)else:last = cache[key]udp_socket.sendto((current[0] + ":" + str(current[1])).encode("utf-8"), last)udp_socket.sendto((last[0] + ":" + str(last[1])).encode("utf-8"), current)del cache[key]print("done:", last, current)udp_socket.close()if __name__ == "__main__":main()
客户端先请求服务端,请求后获取p2p的地址,然后开始周期echo。
client
import socket
import sys
import timedef main():udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)udp_socket.settimeout(10)server = (u"192.168.3.20",2023)key = u"----uni-key-yeshen----"this_client = sys.platform + str(time.time())udp_socket.sendto(key.encode("utf-8"), server)print("waiting..")packet = udp_socket.recvfrom(2048)print("packet",packet)peer = packet[0].split(":")target_peer = (peer[0],int(peer[1]))while True:udp_socket.sendto(this_client.encode("utf-8"), target_peer)print("peer send",this_client,target_peer)msg = udp_socket.recvfrom(2048)print("peer recv",msg)time.sleep(1)udp_socket.close()if __name__ == "__main__":main()
自测效果:
- 在服务端上开启,两个客户端都在同一个局域网里面,有70%左右的概率连通(10个端口,有7个能成功)。数据和wifi都是这样。
- 一个设备在wifi、一个在数据上,连通的概率大约是0%,我还没成功过…