UDP通信时日常中比较常用的一种通信协议,适用于很多的应用场景,例如:微信群聊,QQ群聊等。
1、UDP服务端的创建
import socket
# 创建udp套接字
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定地址
sockdf.bind(('0.0.0.0', 2222))
print('Waiting connect......')
# 循环接收消息
while True:
data, addr = sockdf.recvfrom(1024)
if data == 'close'.encode():
break
print('Recv from {0} information {1}'.format(addr, data))
sockdf.sendto(b'Thanks', addr)
# 关闭套接字
sockdf.close()
2、UDP客户端的创建
import socket
# 服务器地址
ADDR = ('127.0.0.1', 2222)
# 创建套接字
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print('Connect Successful')
# 循环的接收地址
while True:
msg = input('>>>')
if msg == '':
sockdf.sendto(b'close', ADDR)
break
sockdf.sendto(msg.encode(), ADDR)
data, addr = sockdf.recvfrom(1024)
print('接收来自服务端%s的消息%s' % (addr, data.decode()))
# 关闭连接
sockdf.close()
3、UDP协议的应用-----学生信息系统
学生系统服务端
import socket
import struct
import time
ADDR = ('0.0.0.0', 8888)
def Crate_server():
"""
创建udp服务和创建struct的对象
:return:
sockdf:dup服务对象
sf:struct对象
"""
print('Waiting connect......')
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sf = struct.Struct('i20sif')
sockdf.bind(ADDR)
return sockdf, sf
def random_num():
"""
产生每个数据的编号
:return:编号
"""
stu_f = open('stu_info.txt', 'a+')
stu_f.seek(0)
num = 1
for i in stu_f:
num += 1
return num
def wirte_stu(stu_info):
"""
将数据写入到文件中
:param stu_info:数据
:return:None
"""
f = open('stu_info.txt', 'a+')
stu_info[1] = (str(stu_info[1]).split('\\')[0].split('\'')[1])
stu_info.insert(0, random_num())
data = "%d %d %-10s %d %.1f\n" % (tuple(stu_info))
f.write(data)
f.flush()
def read_stu():
"""
获取文件数据
:return: 文件数据
"""
with open('stu_info.txt', 'r') as f:
stu_info = []
for row in f.read().split(' '):
if row != '' and row != '\n':
stu_info.append(row)
stu_info[:] = stu_info[1:5]
stu_info[3] = (str(stu_info[3]).split('\n')[0])
return stu_info
def Server():
"""
循环接收来自客户端的数据
:return:
"""
sockdf, sf = Crate_server()
while True:
try:
data, addr = sockdf.recvfrom(1024)
except KeyboardInterrupt:
break
wirte_stu(list(sf.unpack(data)))
time.sleep(0.5)
successful = '写入成功'
sockdf.sendto(successful.encode(), addr)
sockdf.close()
if __name__ == '__main__':
Server()
学生系统客户端
import socket
import struct
ADDR = ('127.0.0.1', 8888)
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sf = struct.Struct('i20sif')
print('Connect on')
while True:
try:
id = int(input('请输入编号(输入0退出)>>>'))
if id == 0:
break
name = input('请输入姓名>>>')
age = int(input('请输入年龄>>>'))
hight = float(input('请输入身高>>>'))
except KeyboardInterrupt as kberror:
break
names = name.encode()
data = sf.pack(id, names, age, hight)
sockdf.sendto(data, ADDR)
rever, addr = sockdf.recvfrom(1024)
print(rever.decode())
sockdf.close()
4、DUP协议应用(二)—单词查找
单词查找服务端
import socket
def get_world(world):
f = open('dict.txt', 'r')
for data in f:
if data.split(' ', 1)[0] > world:
f.close()
return 'no world'
elif data.split(' ', 1)[0] == world:
f.close()
return data
else:
f.close()
return 'no world'
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sockdf.bind(('0.0.0.0', 8888))
print('Waiting connect......')
while True:
try:
world, addr = sockdf.recvfrom(1024)
except KeyboardInterrupt as kerr:
break
revert_data = get_world(world=world.decode())
sockdf.sendto(revert_data.encode(), addr)
sockdf.close()
单词查找客户端
import socket
ADDR = ('127.0.0.1', 8888)
sockdf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print('Connect Successful')
while True:
try:
msg = input('please enter the world:')
except KeyboardInterrupt as kerr:
break
if msg == ' ':
break
sockdf.sendto(msg.encode(), ADDR)
data, adddr = sockdf.recvfrom(1024)
print(data.decode())