码迷,mamicode.com
首页 > 编程语言 > 详细

python学习_day41_socketserver模块

时间:2017-10-20 21:36:46      阅读:306      评论:0      收藏:0      [点我收藏+]

标签:windows系统   main   eve   http   join   reading   max   server   write   

一、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模块

标签:windows系统   main   eve   http   join   reading   max   server   write   

原文地址:http://www.cnblogs.com/seven-007/p/7701236.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!