python学习_day41_socketserver模块

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习_day41_socketserver模块相关的知识,希望对你有一定的参考价值。

一、socketserver实现并发编程

  如下图socketserver模块中包含基于多线程实现并发编程的类和基于多进程的实现并发编程的类,它其实内部的实现的机制是将我们之前学习实现多线程、多进程的过程封装,按照特定的流程就可以使用,其中常用的还是基于tcp协议通信,多线程的用到的模块是ThreadingTCPServer,多进程用到的模块是ForkingTCPServer,需要说明的是socketserver模块中多进程不能在windows系统中实现,因此这里暂时先主要介绍一下基于TCP协议的多线程实现的方式。

技术分享

  FTP多用户通信实例:

#服务端
import socketserver
import struct
import json
import os
class FtpServer(socketserver.BaseRequestHandler):
    coding=utf-8
    server_dir=file_upload
    max_packet_size=1024
    BASE_DIR=os.path.dirname(os.path.abspath(__file__))
    def handle(self):
        print(self.request)
        while True:
            data=self.request.recv(4)
            data_len=struct.unpack(i,data)[0]
            head_json=self.request.recv(data_len).decode(self.coding)
            head_dic=json.loads(head_json)
            # print(head_dic)
            cmd=head_dic[cmd]
            if hasattr(self,cmd):
                func=getattr(self,cmd)
                func(head_dic)
    def put(self,args):
        file_path = os.path.normpath(os.path.join(
            self.BASE_DIR,
            self.server_dir,
            args[filename]
        ))

        filesize = args[filesize]
        recv_size = 0
        print(----->, file_path)
        with open(file_path, wb) as f:
            while recv_size < filesize:
                recv_data = self.request.recv(self.max_packet_size)
                f.write(recv_data)
                recv_size += len(recv_data)
                print(recvsize:%s filesize:%s % (recv_size, filesize))


ftpserver=socketserver.ThreadingTCPServer((127.0.0.1,8080),FtpServer)
ftpserver.serve_forever()
import socket
import struct
import json
import os



class MYTCPClient:
    address_family = socket.AF_INET

    socket_type = socket.SOCK_STREAM

    allow_reuse_address = False

    max_packet_size = 8192

    coding=utf-8

    request_queue_size = 5

    def __init__(self, server_address, connect=True):
        self.server_address=server_address
        self.socket = socket.socket(self.address_family,
                                    self.socket_type)
        if connect:
            try:
                self.client_connect()
            except:
                self.client_close()
                raise

    def client_connect(self):
        self.socket.connect(self.server_address)

    def client_close(self):
        self.socket.close()

    def run(self):
        while True:
            inp=input(">>: ").strip()
            if not inp:continue
            l=inp.split()
            cmd=l[0]
            if hasattr(self,cmd):
                func=getattr(self,cmd)
                func(l)


    def put(self,args):
        cmd=args[0]
        filename=args[1]
        if not os.path.isfile(filename):
            print(file:%s is not exists %filename)
            return
        else:
            filesize=os.path.getsize(filename)

        head_dic={cmd:cmd,filename:os.path.basename(filename),filesize:filesize}
        print(head_dic)
        head_json=json.dumps(head_dic)
        head_json_bytes=bytes(head_json,encoding=self.coding)

        head_struct=struct.pack(i,len(head_json_bytes))
        self.socket.send(head_struct)
        self.socket.send(head_json_bytes)
        send_size=0
        with open(filename,rb) as f:
            for line in f:
                self.socket.send(line)
                send_size+=len(line)
                print(send_size)
            else:
                print(upload successful)




client=MYTCPClient((127.0.0.1,8080))

client.run()

  上例中实现并发多线程是在服务端,主要实现见如下多用户通信实例:

  服务端:

import socketserver
class Myserver(socketserver.BaseRequestHandler):                         #必须创建一个类,并继承socketserver.BaseRequestHandler类
    def handle(self):                                                    #这个方法必须有,而且方法名不可以更改,它是实例创建连接后自动执行的方法
        while True:
            data=self.request.recv(1024)                                 #self.request相当于conn
            if not data:break
            self.request.send(data.upper())

if __name__ == __main__:
    server=socketserver.ThreadingTCPServer((127.0.0.1,8090),Myserver)  #实例化一个对象
    server.serve_forever()                                               #循环建立连接

  客户端:

import socket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((127.0.0.1,8090))
while True:
    msg=input(>>>).strip()
    if  not msg:
        continue
    client.send(msg.encode())
    data=client.recv(1024)
    print(data.decode())

 

以上是关于python学习_day41_socketserver模块的主要内容,如果未能解决你的问题,请参考以下文章

Python Day41 socketserver实现并发

Python学习_socket学习 & socketserver学习 & IO多路复用

day8 socket socketserver 异常 断言

操作 python基础学习日志day8-socketserver

python开发学习-day08(socket高级socketserver进程线程)

python基础学习日志day8-SocketServer