概述:通信数据交换方式分为几种模式:全双工、半双工和单工数据传输;
问题:什么是全双工、半双工和单工?
解释: 全双工(Full Duplex)是通讯传输的一个术语。
通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。指A→B的同时B→A,是瞬时同步的,四线制。
单工就是在只允许甲方向乙方传送信息,而乙方不能向甲方传送 。
半双工(Half Duplex)数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。例如,在一个局域网上使用具有半双工传输的技术,一个工作站可以在线上发送数据,然后立即在线上接收数据,这些数据来自数据刚刚传输的方向。像全双工传输一样,半双工包含一个双向线路,两线制。
网络编程:对于python而言,同样支持udp和tcp协议完成全双工、半双工和单工的网络通信,本篇文章浅析python的udp协议实现单工、半双工,全双工后面文章分析;
python在网络编程方面提供了socket标准库用以开发实现单工、半双工的网络编程;
具体有以下几个关键方法:
socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 创建udp协议的套接字
socket.bind(loc_addres) # 绑定地址和端口,注意一个参数,元祖类型;
socket.sendto(b"发送内容byte类型",(send_ip,send_port)) # sendto方法两个参数,发送内容和发送目的机器ip地址和端口,机器ip和端口是元祖类型;
socket.recvfrom(1024) # 接受内容,一个参数单次接受字节数大小;
socket.close() # 关闭套接字
单工介绍如下:
先实现发送部分代码:
import socket
def main():
"""实现简单的udp协议单工"""
# 创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 绑定程序端口,如不绑定运行后系统随机分配
loc_addres = ("",5566)
udp_socket.bind(loc_addres)
while True:
# 发送数据的ip和端口
send_ip = input("请输入目的机器的ip:")
send_port = int(input("请输入目的机器的端口:"))
# 发送内容,不同机器有不同编码格式,在发送时候需要关注转码
send_data = input("请输入你需要发送的内容:")
if send_data == "exit":
break
else:
udp_socket.sendto(send_data.encode("utf-8"),(send_ip,send_port)) # 发送目的内容和目的机器ip和端口,元祖类型
#关闭套接字
udp_socket.close()
if __name__ =="__main__":
main()
接收部分代码如下:
import socket
def main():
"""实现简单的udp协议单工调试工具"""
# 创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 绑定程序端口,如不绑定运行后系统随机分配
loc_addres = ("",7788)
udp_socket.bind(loc_addres)
while True:
# 接收其他机器发送的数据
udp_data = udp_socket.recvfrom(1024)
if str(udp_data[1]) == "exit":
break
else:
# 打印接收到的内容
print("%s,%s" %(str(udp_data[1]),udp_data[0].decode("gbk")))
#关闭套接字
udp_socket.close()
if __name__ =="__main__":
main()
调试效果如下:
半双工模式如下:
发送部分实现代码:
import socket
def send_msg(udp_socket):
"""发送数据部分"""
# 发送数据的ip和端口
send_ip = input("请输入目的机器的ip:")
send_port = int(input("请输入目的机器的端口:"))
# 发送内容,不同机器有不同编码格式,在发送时候需要关注转码
send_data = input("请输入你需要发送的内容:")
# 发送数据
udp_socket.sendto(send_data.encode("utf-8"),(send_ip,send_port)) # 发送目的内容和目的机器ip和端口,元祖类型
def recv_msg(udp_socket):
"""接收数据部分"""
udp_data = udp_socket.recvfrom(1024) # 接收目的机器的发送内容
print("%s,%s" %(str(udp_data[1]),udp_data[0].decode("gbk")))
def main():
"""实现简单的udp协议的聊天工具"""
# 创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 绑定程序端口,如不绑定运行后系统随机分配
loc_addres = ("",7799)
udp_socket.bind(loc_addres)
while True:
print("-------*****聊天工具v-0.1-----------")
print("输入0发送数据")
print("输入1接受数据")
print("输入2退出")
req = input("请输入你需要的功能:")
if req == "0":
send_msg(udp_socket)
elif req == "1":
recv_msg(udp_socket)
elif req == "2":
break
else:
print("输入有误请重新输入:")
#关闭套接字
udp_socket.close()
if __name__ =="__main__":
main()
如果在本机调试修改绑定地址端口即可:
# 绑定程序端口,如不绑定运行后系统随机分配
loc_addres = ("",5566)
udp_socket.bind(loc_addres)
调试结果如下: