最近在尝试Socket通信时,发现在UDP协议下,Sever端使用recvfrom方法获取发送端的ip地址和端口号时,IP地址正确,但是端口号总是与Client端sendto方法指定的端口号不一致,代码与结果如下
Sever端:
import socket
# 持续通信
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP类型的套接字
s.bind(("127.0.0.1", 46551)) # 绑定端口,ip可以不写
print("等待接收数据!")
while True:
recv_data, recv_addr = s.recvfrom(1024) # 1024表示本次接收的最大字节数,recvfrom一直监听知道由数据被接受
data = recv_data.decode('gbk')
print(f"收到远程信息:{data},from {recv_addr}")
if data == "exit":
print("结束聊天!")
break
s.close()
Client端:
import socket
# UDP客户端持续发送消息代码
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP类型的套接字
#s.bind(("127.0.0.1", 46552)) #UDPclient端可以不绑定端口,client端不绑定时是随机端口发送的
addr = ("127.0.0.1", 46551)
while True:
data = input("请输入:")
s.sendto(data.encode("gbk"), addr)
if data == "exit":
print("结束聊天!")
break
s.close()
结果:
可以看到终端中输出的信息,Sever端recvfrom方法接收到的端口号不是sendto指定的46551端口,而且每次启动后Sever端接收到的端口都不一样,这里其实是因为在UDP协议下,Client端并没有绑定端口号,所以是由系统随机指定空闲端口发送的,如果在Client端绑定指定的端口 s.bind(("127.0.0.1", 46552))
便可用自己指定的端口 46552
来发送信息。
因为UDP是无连接协议,通信的两端(即发送方和接收方)可以任意选择任何空闲的端口来进行通信,对于接收方来说,获取到的端口号并不一定与发送方所用的端口号相同,而是与发送方所在主机的端口号相同。换句话说,发送方和接收方使用的是各自的端口号来进行通信,而不是共享一个端口号。