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

Cod*_*e47 4 python java sockets socketserver

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

这里是服务器端代码:

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

这里有客户:

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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Rya*_*ing 5

recv不必读取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
Run Code Online (Sandbox Code Playgroud)

这将重复调用recv,sock直到size收到字节.如果part == ''套接字关闭,那么它将返回关闭前的所有内容

所以改变

requestCode = struct.unpack('>i', self.request.recv(4))[0]
Run Code Online (Sandbox Code Playgroud)

requestCode = struct.unpack('>i', recvall(self.request, 4))[0]
Run Code Online (Sandbox Code Playgroud)

我建议recvall你制作一个让你的课更清洁的方法.


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