概述:全双工(Full Duplex)是通讯传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。指A→B的同时B→A,是瞬时同步的。
udp协议:UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
总结:udp没有TCP那么复杂,三次握手,错误重传之类的机制都没有,发的只管发,收得只管收,收到没有?不知道,顺序不对怎么办?不管!就是这样,但是速度就要比TCP高得多了。在对数据帧要求不是很高的地方,这确实是很好用的,比如网络上的视频传输,音频传输等。
思路:python运用socket套接字实现udp的全双工通信如下:
1、创建套接字;
2、绑定地址端口信息(因为没有服务器端转发机制,所以绑定本地端口,方便对方连接);
3、获取对方的ip和端口;
4、引入两个线程,一个线程接收数据一个线程发送数据(具体代码实现见下方)
实现:
客户端一:
import socket
import threading
def recv_msg(udp_socket):
"""接受数据并显示"""
# 接受数据
while True:
recv_data = udp_socket.recvfrom(1024)
print(recv_data)
def send_msg(udp_socket,dest_ip,dest_port):
"""发送数据"""
# 发送数据
while True:
send_data = input("输入要发送的数据:")
udp_socket.sendto(send_data.encode("utf-8"),(dest_ip,dest_port))
def main():
"""完成udp聊天器的整体控制"""
# 1、创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 2、绑定本地信息
udp_socket.bind(("",8899))
# 3、获取对方的ip
dest_ip = input("请输入对方的ip:")
dest_port = int(input("请输入对方的port:"))
# 4、创建线程
t_recv = threading.Thread(target=recv_msg, args=(udp_socket,))
t_send = threading.Thread(target=send_msg, args=(udp_socket,dest_ip,dest_port))
t_recv.start()
t_send.start()
if __name__ == "__main__":
main()
客户端二:(代码基本没有大体变化,主要是端口问题,因为一台机器端口不能重复使用,所以换了端口,如果你开启了虚拟机有两个端口,可以直接使用客户端一代码启动即可)
import socket
import threading
def recv_msg(udp_socket):
"""接受数据并显示"""
# 接受数据
while True:
recv_data = udp_socket.recvfrom(1024)
print(recv_data)
def send_msg(udp_socket,dest_ip,dest_port):
"""发送数据"""
# 发送数据
while True:
send_data = input("输入要发送的数据:")
udp_socket.sendto(send_data.encode("utf-8"),(dest_ip,dest_port))
def main():
"""完成udp聊天器的整体控制"""
# 1、创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 2、绑定本地信息
udp_socket.bind(("",7890))
# 3、获取对方的ip
dest_ip = input("请输入对方的ip:")
dest_port = int(input("请输入对方的port:"))
# 4、创建线程
t_recv = threading.Thread(target=recv_msg, args=(udp_socket,))
t_send = threading.Thread(target=send_msg, args=(udp_socket,dest_ip,dest_port))
t_recv.start()
t_send.start()
if __name__ == "__main__":
main()
调试效果如下:
只是浅析了原理,代码中提示信息是有bug需要细节处理的,结束通信做对应判断处理即可,见谅;