Python3 socket网络编程(三)-socketserver

socketserver

基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环

socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

server类:

 

 

request类:

 

 

继承关系:

 

 

 

 

 

基于tcp的socketserver我们自己定义的类中的

  1. self.server即套接字对象
  2. self.request即一个链接,管道conn
  3. self.client_address即客户端地址

基于udp的socketserver我们自己定义的类中的

  1. self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b'adsf', )
  2. self.client_address即客户端地址
import socketserver

class MyResquestHandle(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request)#如果是tcp协议,self.request相当于conn
        print(self.client_address)

        while True:
            try:
                msg = self.request.recv(1024)
                if len(msg) == 0:
                    break
                self.request.send(msg.upper())
            except Exception:
                break

        self.request.close()


s = socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyResquestHandle)
s.serve_forever()

 

客户端代码和普通的socket代码一样。

import socket

#1.买手机
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#2.拨通电话
phone.connect(('127.0.0.1',8081))

#3.通信
while True:
    msg = input('请输入:').strip()
    if len(msg) == 0:
        continue

    phone.send(msg.encode('utf-8'))

    data = phone.recv(1024)


    print(data.decode('utf-8'))


#关闭连接必选
phone.close()

 

 

 

  socketserver有以下几种类型:

  TCPServer:tcp协议

class socketserver.TCPServer(server_address,RequestHandlerClass,bind_and_activate=True)
 

  ThreadingTCPServer:多线程,多并发的TCPServer

class socketserver.ThreadingTCPServer(server_address,RequestHandlerClass,bind_and_activate=True)
 

  ForkingTCPServer:多进程,多并发的TCPServer #在windows中不能使用这个

class socketserver.ForkingTCPServer(server_address,RequestHandlerClass,bind_and_activate=True)
 

  UDPServer:udp协议

class socketserver.UDPServer(server_address,RequestHandlerClass,bind_and_activate=True)
 

  UnixStreamServer:tcp协议,Unix本机间不同进程间通信可以使用这个server

class socketserver.UnixStreamServer(server_address,RequestHandlerClass,bind_and_activate=True)
 

  UnixDatagramServer:udp协议,Unix本机间不同进程间通信可以使用这个server

class socketserver.UnixDatagramServer(server_address,RequestHandlerClass,bind_and_activate=True)	
 

  BaseServer是所有Server类型的基类。

  TCPServer继承了BaseServer,UnixStreamServer继承了TCPServer。

  UDPServer继承了TCPServer,UnixDatagramServer继承了UDPServer。

  BaseServer有以下这些方法:

    fileno():返回文件描述符

    handle_request():处理单个请求

    serve_forever(poll_interval=0.5):处理多个请求

      poll_interval用来设置多长时间检查一下是否有收到shutdown()请求

      当收到shutdown()请求后,调用service_actions(),serve_forever将停止提供服务

    shutdown():告诉serve_forever()让其停掉

    server_close():关闭服务

 

  创建socketserver的步骤:

  1、创建一个BaseRequestHandlerclass的子类并在子类中重写handle()方法

    这个子类用来处理客户端的请求

    与客户端所有的交互都是在handle()方法中编写

  2、实例化一个server(如TCPServer)类,并且将Server_IP和上一步创建的子类传给这个实例化的类(此处是       TCPServer)作为参数

  3、调用第2步实例化出来的对象的方法,这里假定这个实例化出来的对象为server:

    server.handle_request():只处理一个请求,处理完后退出

    server.serve_forever():处理多个请求,永远执行

  4、调用close()方法关闭server

 

  重写BaseRequestHandlerclass类的handle()方法:

def handle(self):
    #self.request is the TCP socket connected to the client
    self.data = self.request.recv(1024).strip()
    print("{} wrote:".format(self.client_address[0]))
    print(self.data)
    #just send back the same data,but upper-cased
    self.request.sendall(self.data.upper())
    #sendall其实就是重复调用send,在这里也可以用send


基于UDP无链接的简单并发程序

服务端:

import socketserver


# 自定义类来实现通信循环
class MyUDPHander(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', 8080), MyUDPHander)
    server.serve_forever()  # 链接循环

客户端1/2/3/4……:

from socket import *

client = socket(AF_INET,SOCK_DGRAM)

while True:
    client.sendto(b'hello',('127.0.0.1',8080))
    data,server_add = client.recvfrom(1024)
    print(data)
 
posted @ 2021-01-19 16:06  云long  阅读(863)  评论(0编辑  收藏  举报