我遇到一个简单的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个字节。
我尝试编写一个执行java客户端相同操作的Python客户端,在这种情况下,服务器的recv(4)
运行良好。
如何解决这个问题?我想实现一个简单的python buffered reader function
,它逐字节地读取套接字,但我确信存在更智能的解决方案。
答案 0 :(得分: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
这将在recv
上重复调用sock
,直到收到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
答案 1 :(得分:0)
recv(4)将读取4个字节的最大值。请参阅文档:http://docs.python.org/library/socket.html。我认为制作一个简单的缓冲读卡器功能是一个完全可以接受的解决方案。
答案 2 :(得分:0)
也许你可以使用io模块中的内容?例如BufferedRWPair。