python-基于UDP通信的套接字,socketserver模块的使用

时间:2023-03-09 15:54:24
python-基于UDP通信的套接字,socketserver模块的使用

一、基于UDP协议通信的套接字

udp是没有链接的,所以先启动哪一端都不会报错

import socket

server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8082)) while True:
data,client_addr=server.recvfrom(1024)
print(data)
server.sendto(data.upper(),client_addr) server.close()

server

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
msg=input('>>: ').strip()
client.sendto(msg.encode('utf-8'),('127.0.0.1',8082))
data,server_addr=client.recvfrom(1024)
print(data)

client

由于udp无连接,所以可以同时多个客户端去跟服务端通信(实现简单的并发,并不可靠)

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
msg=input('>>: ').strip()
client.sendto(msg.encode('utf-8'),('127.0.0.1',8082))
data,server_addr=client.recvfrom(1024)
print(data)

client2

udp不会出现粘包现象,因为每个中就已经有了报头,这样对于接收端来说,容易区分处理。

udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendinto(y),收完了x个字节的数据就算完成,若是y>x数据就丢失,这意味着udp根本不会粘包,但是会丢数据,不可靠

二、socketserver模块

socketserver模块简化了编写网络服务程序的任务,是python标准库中很多服务器框架的基础。

socketserver中包含了两种类,一种为服务类(server class),一种为请求处理类(request handle class),前者主要做的是建立链接的过程,后者注重用户数据的处理

要实现一项服务,还必须派生一个handler class请求处理类,并重写父类的handle()方法。handle方法就是用来专门是处理请求的。该模块是通过服务类和请求处理类组合来处理请求的。SocketServer模块提供的请求处理类有BaseRequestHandler。

1.基于tcp协议通信

# 服务端必须满足至少三点:
# 1. 绑定一个固定的ip和port
# 2. 一直对外提供服务,稳定运行
# 3. 能够支持并发
import socketserver # 自定义类用来处理通信循环
class MyTCPhanler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
data = self.request.recv(1024)
if len(data) == 0: break # 针对linux系统
print('-->收到客户端的消息: ', data)
self.request.send(data.upper())
except ConnectionResetError:
break self.request.close() if __name__ == '__main__':
server=socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyTCPhanler)
server.serve_forever() # 链接循环

server

from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081)) # 通信循环
while True:
# msg=input('>>: ').strip() #msg=''
# if len(msg) == 0:continue
# client.send(msg.encode('utf-8')) #client.send(b'')
client.send('hello'.encode('utf-8')) #client.send(b'')
# print('has send')
data=client.recv(1024)
# print('has recv')
print(data) client.close()

client1

from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081)) # 通信循环
while True:
# msg=input('>>: ').strip() #msg=''
# if len(msg) == 0:continue
# client.send(msg.encode('utf-8')) #client.send(b'')
client.send('hello'.encode('utf-8')) #client.send(b'')
# print('has send')
data=client.recv(1024)
# print('has recv')
print(data) client.close()

client2

2.基于udp协议通信

import socketserver

class MyUdphandler(socketserver.BaseRequestHandler):
def handle(self):
data,sock=self.request
sock.sendto(data.upper(),self.client_address) if __name__ == '__main__':
server=socketserver.ThreadingUDPServer(('127.0.0.1',8081),MyUdphandler)
server.serve_forever()

server

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
client.sendto(b'hello',('127.0.0.1',8081))
data,server_addr=client.recvfrom(1024)
print(data)

client1

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
client.sendto(b'hello',('127.0.0.1',8081))
data,server_addr=client.recvfrom(1024)
print(data)

client2