网络编程-基于socketserver模块实现并发的套接字

https://www.cnblogs.com/gaohuayan/p/11139397.html 关于listen的解释
https://blog.51cto.com/120662/1733142 ThreadingTCPServer源码分析

socketserver介绍

socketserver 是标准库中的一个高级模块, socketserver 模块是python提供的内置的用于快捷开发服务端程序的一个服务器框架,通过封装大量实现的方式减少开发人员工作量的同时能快捷开发出具有较高质量的服务端程序;

基础版本

服务端

import socketserver
import time
class MyHandler(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.client_address) # 客户端的ip端口
        print(self.request) # 相当于本次来的客户端的连接对象
        #<socket.socket fd=544, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 62552)>
        time.sleep(60)
        print('===>')
if __name__ == '__main__':
    s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyHandler,bind_and_activate=True)
    # 第一个参数为服务端绑定的ip和端口
    # 第二个参数可以实现为每接到的连接进行的通讯处理
    # 第三个参数进行 bind 和 listen方法
    s.serve_forever()  # 代表连接循环
    # 循环建立连接,每建立一个连接就会启动一个线程(服务员)+调用Myhanlder类产生一个对象,调用该对象下的handle方法,专门与刚刚建立好的连接做通信循环

客户端

import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) # 指定服务端ip和端口

while True:
    # msg=input('>>: ').strip() #msg=''
    msg = 'client01'  # msg=''
    if len(msg) == 0:continue
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)
    print(data)
phone.close()

具体操作

分别启动三个客户端观察效果(见下图):
思考:先有链接--才有通讯,通讯结束后才去重新接受下一个链接。
而现在的演示效果是,通讯循环并没有结束,而新的通讯循环也开始执行了,所以证明建立链接的时候是并发的,并没与等待通讯循环结束(这底层是依靠线程实现的,后面我们会详细讲解)

演示效果是:

为服务端代码增加通讯循环

import socketserver

class MyHandler(socketserver.BaseRequestHandler):
    def handle(self):
        #通信循环
        while True:
            # print(self.client_address)
            # print(self.request) #self.request=conn

            try:
                data=self.request.recv(1024)
                if len(data) == 0:break
                self.request.send(data.upper())
            except ConnectionResetError:
                break


if __name__ == '__main__':
    s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyHandler,bind_and_activate=True)

    s.serve_forever()  # 代表连接循环
    # 循环建立连接,每建立一个连接就会启动一个线程(服务员)+调用Myhanlder类产生一个对象,调用该对象下的handle方法,专门与刚刚建立好的连接做通信循环

ThreadingTCPServer源码分析

待整理

posted @ 2019-09-06 13:11  张明岩  阅读(144)  评论(0)    收藏  举报