来自java客户端的Python套接字recv

Posted

技术标签:

【中文标题】来自java客户端的Python套接字recv【英文标题】:Python socket recv from java client 【发布时间】:2012-08-05 23:42:19 【问题描述】:

我有一个简单的 python tcp 服务器问题(我正在使用SocketServer 类),它必须从 java 客户端接收数据。

这里是服务器端代码:

class ServerRequestHandler(SocketServer.BaseRequestHandler):
    [...]
    def handle(self):
        requestCode = struct.unpack('>i', self.request.recv(4))[0]
        [...]
    [...]

这里是客户端:

addr = InetAddress.getByName(hostname);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
clientSocket = new Socket();
clientSocket.connect(sockaddr, timeoutMs);
clientSocketDataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
int   requestCode = 1;
clientSocketDataOutputStream.writeInt(requestCode);
clientSocketDataOutputStream.flush();

我启动 Python 服务器,然后尝试执行必须向服务器发送整数的客户端。

在服务器端 Python 引发异常,因为 recv(4) 函数不读取 4 个字节,它只返回一个字节。

事实上,我的 java 客户端正确发送了 4 个字节,如果我尝试调用 recv(1) 4 次,它会正确读取 4 个字节。

我尝试编写一个 Python 客户端来执行与我的 java 客户端相同的操作,在这种情况下,服务器的 recv(4) 运行良好。

如何解决这个问题?我想实现一个简单的 python buffered reader function 逐字节读取套接字,但我确信存在更智能的解决方案。

【问题讨论】:

【参考方案1】:

recv 不必读取 4 个字节,它只抓取最多 4 个字节的任何内容。因为,正如您所说,您可以调用 recv(1) 4 次。你可以这样做

def recvall(sock, size):
    msg = ''
    while len(msg) < size:
        part = sock.recv(size-len(msg))
        if part == '': 
            break # the connection is closed
        msg += part
    return msg

这将在sock 上重复调用recv,直到收到size 字节。如果part == '' 套接字已关闭,那么它将返回关闭之前的任何内容

所以改变

requestCode = struct.unpack('>i', self.request.recv(4))[0]

requestCode = struct.unpack('>i', recvall(self.request, 4))[0]

我建议将recvall 设置为您的类的方法以使事情变得更清洁。


这是对此处定义的安全套接字类的方法的修改:http://docs.python.org/howto/sockets.html

【讨论】:

【参考方案2】:

也许你可以使用来自io 模块的东西?以BufferedRWPair 为例。

【讨论】:

【参考方案3】:

recv(4) 将读取 最大 4 个字节。请参阅文档:http://docs.python.org/library/socket.html。我认为在这里制作一个简单的缓冲阅读器功能是一个完全可以接受的解决方案。

【讨论】:

以上是关于来自java客户端的Python套接字recv的主要内容,如果未能解决你的问题,请参考以下文章

如果达到超时,gen_tcp:recv/3 是不是会关闭套接字?

TCP阻塞模型下服务器和客户端的建立步骤

C#异步套接字服务器没有收到来自Java客户端的响应

Python套接字服务器读取客户端的多命令[关闭]

Python套接字recv()由于硬件而挂起?

无法解码来自客户端的握手请求