一、UDP套接字简单示例
1.1 服务端
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》UDP
server.bind(('127.0.0.1', 8080))
while True:
data, client_addr = server.recvfrom(1024)
print('===>', data, client_addr)
server.sendto(data.upper(), client_addr)
server.close()
二、客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》UDP
while True:
msg = input('>>: ').strip() # msg=''
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
data, server_addr = client.recvfrom(1024)
print(data)
client.close()
- UDP是无链接的,先启动哪一端都不会报错
- UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到
三、UPD套接字无粘包问题
3.1 服务端
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp
server.bind(('127.0.0.1', 8080))
data, client_addr = server.recvfrom(1024) # b'hello'==>b'h'
print('第一次:', client_addr, data)
data, client_addr = server.recvfrom(1024) # b'world' =>b'world'
print('第二次:', client_addr, data)
#
# data,client_addr=server.recvfrom(1024)
# print('第三次:',client_addr,data)
server.close()
3.2 客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp
client.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8080))
client.sendto('world'.encode('utf-8'), ('127.0.0.1', 8080))
# client.sendto(''.encode('utf-8'),('127.0.0.1',8080))
client.close()
- UPD协议一般不用于传输大数据。
- UDP套接字虽然没有粘包问题,但是不能替代TCP套接字,因为UPD协议有一个缺陷:如果数据发送的途中,数据丢失,则数据就丢失了,而TCP协议则不会有这种缺陷,因此一般UPD套接字用户无关紧要的数据发送,例如qq聊天。
四、qq聊天
- 由于UDP无连接,所以可以同时多个客户端去跟服务端通信
4.1 服务端
#_*_coding:utf-8_*_
__author__ = 'nick'
import socket
ip_port = ('127.0.0.1', 8081)
UDP_server_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #买手机
UDP_server_sock.bind(ip_port)
while True:
qq_msg, addr = UDP_server_sock.recvfrom(1024)
print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %
(addr[0], addr[1], qq_msg.decode('utf-8')))
back_msg = input('回复消息: ').strip()
UDP_server_sock.sendto(back_msg.encode('utf-8'), addr)
4.2 客户端1
#_*_coding:utf-8_*_
__author__ = 'nick'
import socket
BUFSIZE = 1024
UDP_client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
qq_name_dic = {
'狗哥alex': ('127.0.0.1', 8081),
'瞎驴': ('127.0.0.1', 8081),
'一棵树': ('127.0.0.1', 8081),
'武大郎': ('127.0.0.1', 8081),
}
while True:
qq_name = input('请选择聊天对象: ').strip()
while True:
msg = input('请输入消息,回车发送: ').strip()
if msg == 'quit': break
if not msg or not qq_name or qq_name not in qq_name_dic: continue
UDP_client_socket.sendto(msg.encode('utf-8'), qq_name_dic[qq_name])
back_msg, addr = UDP_client_socket.recvfrom(BUFSIZE)
print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %
(addr[0], addr[1], back_msg.decode('utf-8')))
UDP_client_socket.close()
4.3 客户端2
#_*_coding:utf-8_*_
__author__ = 'nick'
import socket
BUFSIZE = 1024
UDP_client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
qq_name_dic = {
'狗哥alex': ('127.0.0.1', 8081),
'瞎驴': ('127.0.0.1', 8081),
'一棵树': ('127.0.0.1', 8081),
'武大郎': ('127.0.0.1', 8081),
}
while True:
qq_name = input('请选择聊天对象: ').strip()
while True:
msg = input('请输入消息,回车发送: ').strip()
if msg == 'quit': break
if not msg or not qq_name or qq_name not in qq_name_dic: continue
UDP_client_socket.sendto(msg.encode('utf-8'), qq_name_dic[qq_name])
back_msg, addr = UDP_client_socket.recvfrom(BUFSIZE)
print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %
(addr[0], addr[1], back_msg.decode('utf-8')))
UDP_client_socket.close()
4.4 运行结果
![125-基于UDP协议的套接字编程-聊天1.png?x-oss-process=style/watermark](http://www.chenyoude.com/Python%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/125-%E5%9F%BA%E4%BA%8EUDP%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%A5%97%E6%8E%A5%E5%AD%97%E7%BC%96%E7%A8%8B-%E8%81%8A%E5%A4%A91.png?x-oss-process=style/watermark)
![125-基于UDP协议的套接字编程-聊天2.png?x-oss-process=style/watermark](http://www.chenyoude.com/Python%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/125-%E5%9F%BA%E4%BA%8EUDP%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%A5%97%E6%8E%A5%E5%AD%97%E7%BC%96%E7%A8%8B-%E8%81%8A%E5%A4%A92.png?x-oss-process=style/watermark)
![125-基于UDP协议的套接字编程-聊天3.png?x-oss-process=style/watermark](http://www.chenyoude.com/Python%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/125-%E5%9F%BA%E4%BA%8EUDP%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%A5%97%E6%8E%A5%E5%AD%97%E7%BC%96%E7%A8%8B-%E8%81%8A%E5%A4%A93.png?x-oss-process=style/watermark)