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())