【问题标题】:How to recv large files using socketserver?如何使用 socketserver 接收大文件?
【发布时间】:2015-06-05 20:58:21
【问题描述】:

服务器端recv并为客户端发回数据:

import socketserver

    class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

        def handle(self):
            try:
                data = b''
                while True:
                    package = self.request.recv(4096)
                    if not package:
                        break
                    data = data + package
                self.request.sendall(data)
            except ConnectionError as conError:
                print(conError)

    class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
        pass

    if __name__ == "__main__":
        HOST, PORT = "localhost", 50007
        print('Server start work!')
        server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
        ip, port = server.server_address
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            print('Server stop by Keyboard Interrupt.')

客户端读取txt文件,发送到服务器等待回复:

def send_msg(data):
    import socket
    HOST = 'localhost'   
    PORT = 50007             
    reply = ''
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            s.sendall(data)
            while True:
                data = s.recv(4096)
                if not data:
                    break
                reply = reply+data.decode()
    except OSError as err:
        reply = err
    finally:
        return reply
#some.txt is big txt file
with open(r'some.txt', 'rb') as of:
    print(send_msg(of.read()))

但是在最后一块数据之后实现了这个“挂起”。我的问题是,需要改变什么,才能获得所有数据。

【问题讨论】:

  • 请考虑使用异步框架,例如circuitsTwisted
  • 我也实现了一个非常类似的解决方案,在这里可能会做你想做的事:stackoverflow.com/questions/30620681/…
  • 谢谢,但两者都不包含在框架中,是pothon 3.4的基本集,对于手头的任务是不可接受的。
  • 如果这不是通过 socketserver 完成的,我将尝试仅使用 socket 来实现我的服务器。然而,也许还有选择?
  • 发送数据后,您必须关闭该方向的 TCP 连接,以便对方知道没有更多数据进来。否则,recv() 会阻塞等待其他数据。

标签: python windows


【解决方案1】:

我在前10个字符中解决了如下问题我发送的数据大小要接收,服务器端检查接收到的数据,如果是客户端发送的较少,则继续接收数据。

所以你需要修改服务器端:

import socketserver

    class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

        def handle(self):
            try:
                 package = self.request.recv(4096)
                 data_size = package[:10].strip(b'0')
                 data = package[10:]
                 while len(data) < int(data_size):
                     package = self.request.recv(4096)
                     if not package:
                       break
                 data = data + package
                 self.request.sendall(data)
            except ConnectionError as conError:
                print(conError)

    class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
        pass

    if __name__ == "__main__":
        HOST, PORT = "localhost", 50007
        print('Server start work!')
        server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
        ip, port = server.server_address
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            print('Server stop by Keyboard Interrupt.')

客户端:

def send_msg(data):
    import socket
    HOST = 'localhost'   
    PORT = 50007             
    reply = ''
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            s.sendall(str(len(data)).encode().zfill(10)+data)
            while True:
                data = s.recv(4096)
                if not data:
                    break
                reply = reply+data.decode()
    except OSError as err:
        reply = err
    finally:
        return reply
#some.txt is big txt file
with open(r'some.txt', 'rb') as of:
    print(send_msg(of.read()))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 2012-12-21
    • 1970-01-01
    • 2011-10-29
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多