目 录
一、基于UDP协议的基本通信
import socket server = socket.socket(type=socket.SOCK_DGRAM) # UDP协议 server.bind(('127.0.0.1',8080)) # UDP不需要设置半连接池 它也没有半连接池的概念 # 因为没有双向通道 不需要accept 直接就是通信循环 while True: data, addr = server.recvfrom(1024) print('数据:',data) # 客户端发来的消息 print('地址:',addr) # 客户端的地址 server.sendto(data.upper(),addr)
import socket client = socket.socket(type=socket.SOCK_DGRAM) # 不需要建立连接 直接进入通信循环 server_address = ('127.0.0.1',8080) while True: client.sendto(b'hello',server_address) data, addr = client.recvfrom(1024) print('服务端发来的数据',data) print('服务端的地址',addr)
二、UDP 通信的特点
""" UDP通信 数据报协议(自带报头) 没有双向通道 通信类似于发短信 1.udp协议客户端允许发空 2.udp协议不会粘包 3.udp协议服务端不存在的情况下,客户端照样不会报错 4.udp协议支持并发 """
除此之外与tcp区别:
基于连接与无连接;对系统资源的要求(TCP较多,UDP较少);UDP程序结构简单; tcp流式模式,udp数据报模式。
UDP通信不会出现黏包问题,代码展示如下:
import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1', 8080)) # while True: data, addr = server.recvfrom(1024) print('客户端1发来数据:',data) data, addr = server.recvfrom(1024) print('客户端2发来数据:', data) data, addr = server.recvfrom(1024) print('客户端3发来数据:', data)
import socket client = socket.socket(type=socket.SOCK_DGRAM) server_address = ('127.0.0.1',8080) # while True: # msg = input('>>>:') client.sendto(b'hello',server_address) client.sendto(b'hello',server_address) client.sendto(b'hello',server_address) # data, server_addr = client.recvfrom(1024) # print(data)
三、基于UDP通信的简易版QQ
import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1',8080)) while True: data, addr = server.recvfrom(1024) print(data.decode('utf-8')) r_msg = input('>>>: ').strip() r_msg = f'来自服务端的数据:{r_msg}' server.sendto(r_msg.encode('utf-8'),addr)
import socket client = socket.socket(type=socket.SOCK_DGRAM) server_adress = ('127.0.0.1',8080) while True: msg = input('>>>: ').strip() msg = '来自客户端1的消息:%s' % msg msg = msg.encode('utf-8') client.sendto(msg,server_adress) data, addr = client.recvfrom(1024) print(data.decode('utf-8'))
import socket client = socket.socket(type=socket.SOCK_DGRAM) server_adress = ('127.0.0.1',8080) while True: msg = input('>>>: ').strip() msg = '来自客户端2的消息:%s' % msg msg = msg.encode('utf-8') client.sendto(msg,server_adress) data, addr = client.recvfrom(1024) print(data.decode('utf-8'))
import socket client = socket.socket(type=socket.SOCK_DGRAM) server_adress = ('127.0.0.1',8080) while True: msg = input('>>>: ').strip() msg = '来自客户端3的消息:%s' % msg msg = msg.encode('utf-8') client.sendto(msg,server_adress) data, addr = client.recvfrom(1024) print(data.decode('utf-8'))
import socket client = socket.socket(type=socket.SOCK_DGRAM) server_adress = ('127.0.0.1',8080) while True: msg = input('>>>: ').strip() msg = '来自客户端4的消息:%s' % msg msg = msg.encode('utf-8') client.sendto(msg,server_adress) data, addr = client.recvfrom(1024) print(data.decode('utf-8'))
四、socketserver模块
利用socketserver模块实现TCP并发功能
一句话总结socketserver模块的作用:
能够实现并发的效果!
需求如下:
""" 需求: 利用socketserver模块使得TCP能够实现像UDP一样,看上去像是同时运行, 多个客户端连接服务端,多个客户端都不在被服务 """
import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): # print('来啦 老弟') while True: data = self.request.recv(1024) print(self.client_address) # 客户端地址 print(data.decode('utf-8')) self.request.send(data.upper()) if __name__ == '__main__': """只要有客户端连接 会自动交给自定义类中的handle方法去处理""" server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象 server.serve_forever() # 启动该服务对象
import socket client = socket.socket() client.connect(('127.0.0.1',8080)) while True: client.send(b'hello') data = client.recv(1024) print(data.decode('utf-8'))
利用socketserver模块实现UDP通信
import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): # print('来啦 老弟') while True: data,sock = self.request print(self.client_address) # 客户端地址 print(data.decode('utf-8')) sock.sendto(data.upper(),self.client_address) if __name__ == '__main__': """只要有客户端连接 会自动交给自定义类中的handle方法去处理""" server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象 server.serve_forever() # 启动该服务对象
import socket import time client = socket.socket(type=socket.SOCK_DGRAM) server_address = ('127.0.0.1',8080) while True: client.sendto(b'hello',server_address) data,addr = client.recvfrom(1024) print(data.decode('utf-8'),addr) time.sleep(1)