基于udp套接字
udp是无链接的,先启动哪一端都不会报错。
UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。不会发生粘包现象。
例子 1、
服务端
from socket import * server=socket(AF_INET,SOCK_DGRAM) server.bind(('127.0.0.1',8080)) while True: data,client_addr=server.recvfrom(1024) print('客户端的数据: ',data) server.sendto(data.upper(),client_addr)
客户端
from socket import * client=socket(AF_INET,SOCK_DGRAM) while True: msg=input('>>: ').strip() client.sendto(msg.encode('utf-8'),('127.0.0.1',8080)) data,server_addr=client.recvfrom(1024) print(data.decode('utf-8'))
例子2、
服务端
from socket import * sever=socket(AF_INET,SOCK_DGRAM) #创建服务器套接字 sever.bind(('127.0.0.1',8090)) #绑定服务器套接字 while True: #服务器循环 data,addr_client=sever.recvfrom(1024) #接收对话 print(data.decode('utf-8')) msg=input('>>>').strip() if msg=='q':break sever.sendto(msg.encode('utf-8'),addr_client) #发送对话 sever.close() #关闭服务器套接字
客户端
from socket import * client=socket(AF_INET,SOCK_DGRAM) #创建客户套接字 while True: #通讯循环 msg=input('>>>').strip() if msg == 'q': break client.sendto(msg.encode('utf-8'),('127.0.0.1',8090)) #发送消息 data,addr_sever=client.recvfrom(1024) #接收消息 print(data.decode('utf-8')) client.close() #关闭客户套接字
例子3、qq聊天
服务端
import socket ip_port=('127.0.0.1',8081) sever=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) sever.bind(ip_port) while True: qq_msg,addr=sever.recvfrom(1024) print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %(addr[0],addr[1],qq_msg.decode('utf-8'))) back_msg=input('回复消息: ').strip() sever.sendto(back_msg.encode('utf-8'),addr)
客户1
import socket client=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), 'egon':('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 client.sendto(msg.encode('utf-8'),qq_name_dic[qq_name]) back_msg,addr=client.recvfrom(1024) print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %(addr[0],addr[1],back_msg.decode('utf-8'))) udp_client_socket.close()
客户2
import socket client=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), 'egon':('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 client.sendto(msg.encode('utf-8'),qq_name_dic[qq_name]) back_msg,addr=client.recvfrom(1024) print('来自[%s:%s]的一条消息: 33[1;44m%s 33[0m' %(addr[0],addr[1],back_msg.decode('utf-8'))) udp_client_socket.close()
补充问题一:为何tcp是可靠传输,udp是不可靠传输
tcp在数据传输时,发送端先把数据发送到自己的缓存中,然后协议控制将缓存中的数据发往对端,对端返回一个ack=1,发送端则清理缓存中的数据,对端返回ack=0,则重新发送数据,所以tcp是可靠的
而udp发送数据,对端是不会返回确认信息的,因此不可靠