receiver:
import socket
def recv_judge_nat_type(port:int)->None:
# 1.创建一个udp套接字对象
udp=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配
# 30000 表示本地的端口 ip一般不用写
udp.bind(("",port))
# 3. 等待接收对方发送的数据
recv_data=udp.recvfrom(1024)
# 1024表示本次接收的最大字节数
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的编码后的数据
# 第2个元素是对方的ip和端口
data=recv_data[0].decode('gbk').split(':')
saddr_private=data[0]
sport_private=int(data[1])
saddr=recv_data[1][0]
sport=recv_data[1][1]
print("The data after decoding is ",data)
print("source ip is ",saddr,", and source port is",sport)
print(saddr,saddr_private)
if saddr==saddr_private and sport==sport_private:
print("No NAT!")
else:print("NAT applies!")
#往saddr:sport发数据
udp.sendto((saddr+':'+str(sport)).encode("utf-8"),(saddr,sport))
# 3.关闭套接字
udp.close()
port=30000
recv_judge_nat_type(port)
send
import socket
def send_judge_nat_type(saddr:str,sport:int,daddr:str,dport:int)->None:
# 1.创建一个udp套接字对象
udp=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
local_addr=("",sport)
udp.bind(local_addr)
# 2.准备接收方的地址
#sendto 的第一个参数需要一个字节类型,所以需要编码一下
udp.sendto((saddr+':'+str(sport)).encode("utf-8"),(daddr,dport))
'''sendto(data[, flags], address) -> count, Like send(data, flags) but allow
s specifying the destination address. For IP sockets, the address is a pair
(hostaddr, port).'''
recv_data=udp.recvfrom(1024)
data=recv_data[0].decode('gbk').split(':')
addr=data[0]
port=int(data[1])
print("The data after decoding is ",data)
print(addr,port)
# 3.关闭套接字
udp.close()
return
saddr="192.168.1.120"
daddr="192.168.1.124"
sport=40000#source port
dport=30000#targer port
send_judge_nat_type(saddr,sport,daddr,dport)#port must be 0-65535