在远程使用所有数据之前,Python套接字已关闭

Nic*_*uma 6 python sockets

我正在编写一个Python模块,它通过unix套接字与go程序进行通信.客户端(python模块)将数据写入套接字,服务器使用它们.

# Simplified version of the code used
outputStream = socket.socket(socketfamily, sockettype, protocol)
outputStream.connect(socketaddress)
outputStream.setblocking(True)
outputStream.sendall(message)
....
outputStream.close()
Run Code Online (Sandbox Code Playgroud)

我的问题是,在服务器有效读取数据之前,Python客户端倾向于完成并关闭套接字,从而导致服务器端的"管道损坏,连接重置".无论我做什么,对于Python代码,一切都已发送,因此对send()sendall()select()的调用都是成功的...

提前致谢

编辑:由于mac OS我无法使用关机

EDIT2:我也试图删除超时并调用setblocking(True),但它不会改变任何东西

编辑3:准备好这个问题后http://bugs.python.org/issue6774似乎文档是不必要的可怕所以我恢复了关机但我仍然有同样的问题:

# Simplified version of the code used
outputStream = socket.socket(socketfamily, sockettype, protocol)
outputStream.connect(socketaddress)
outputStream.settimeout(5)
outputStream.sendall(message)
....
outputStream.shutdown(socket.SHUT_WR)
outputStream.close()
Run Code Online (Sandbox Code Playgroud)

Jam*_*lls 0

IHMO 这最好使用异步 I/O 库/框架来完成。这是使用电路的解决方案:

服务器将收到的内容回显到标准输出,客户端打开一个文件并将其发送到服务器,等待它完成,然后关闭套接字并终止。这是通过异步 I/O 和协程的混合来完成的。

服务器.py:

from circuits import Component
from circuits.net.sockets import UNIXServer

class Server(Component):

    def init(self, path):
        UNIXServer(path).register(self)

    def read(self, sock, data):
        print(data)

Server("/tmp/server.sock").run()
Run Code Online (Sandbox Code Playgroud)

客户端.py:

import sys

from circuits import Component, Event
from circuits.net.sockets import UNIXClient
from circuits.net.events import connect, close, write

class done(Event):
    """done Event"""

class sendfile(Event):
    """sendfile Event"""

class Client(Component):

    def init(self, path, filename, bufsize=8192):
        self.path = path
        self.filename = filename
        self.bufsize = bufsize

        UNIXClient().register(self)

    def ready(self, *args):
        self.fire(connect(self.path))

    def connected(self, *args):
        self.fire(sendfile(self.filename, bufsize=self.bufsize))

    def done(self):
        raise SystemExit(0)

    def sendfile(self, filename, bufsize=8192):
        with open(filename, "r") as f:
            while True:
                try:
                    yield self.call(write(f.read(bufsize)))
                except EOFError:
                    break
                finally:
                    self.fire(close())
                    self.fire(done())

Client(*sys.argv[1:]).run()
Run Code Online (Sandbox Code Playgroud)

在我对此的测试中,它的行为完全符合我的预期,没有错误,并且服务器在客户端关闭套接字并关闭之前获取完整的文件。