Python套接字从Java PrintWriter套接字接收不完整的消息

我创建了一个python“队列”(类似于JMS协议),它将从两个Java客户端收到问题。 python-server将从其中一个Java客户端接收消息,第二个将读取问题并发布答案。 连接和消息传递工作,当Java客户端使用长度很长的String进行应答时,就会出现问题。

python收到的响应不完整! 更糟糕的是,消息被剪切为一定数量的字符并且始终保持相同的长度,但是,如果其他人托管服务器,则该数字是不同的。 (即:friend1托管服务器,friend2发送响应,收到长度:1380chars.Friend2托管服务器,friend1发布答案,收到长度:1431chars)这是服务器端python代码:

s = socket.socket() host = socket.gethostname() # host = "192.168.0.20" port = 12345 s.bind((host, port)) s.listen(5) while True: c, addr = s.accept() # print 'Got connection from', addr message = c.recv(8192) #Is this length a problem? # print message message = message.strip() ipAddress = addr[0] 

我在这里阅读StackOverflow上的问题,c.recv()应该没有大量字节的问题,我们的响应接近1500个字符。 这是java客户端:

 private void openConnection(){ try { socket = new Socket(HOST, PORT); out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( socketPregunta.getInputStream())); stdIn = new BufferedReader(new InputStreamReader(System.in)); } catch (Exception e) {} } public void sendAnswer(String answer) throws IOException{ openConnection(); out.write("PUBLISH-" + answer); //This answer is send incomplete! out.flush(); closeConnection(); } 

提前致谢!

从文档:

recv(buffersize [,flags]) – >数据

接收来自套接字的缓冲区字节。 有关可选的flags参数,请参阅Unix手册。 当没有可用数据时,阻塞直到至少有一个字节可用或直到远程端关闭。 关闭远程端并读取所有数据后,返回空字符串。

所以recv()可以返回比你要求的更少的字节,这就是你的情况。 在socket howto中讨论了这个问题。

基本上你需要继续调用recv()直到你收到一个完整的消息,或者远程对等体已经关闭了连接(由recv()发出的返回空字符串的信号)。 你如何做到这一点取决于你的协议。 选项是:

  1. 使用固定大小的消息
  2. 有某种分隔符或标记来检测消息的结束
  3. 让客户端提供消息长度作为消息的一部分
  4. 让客户端在完成发送消息后关闭连接。 显然,在这种情况下,它将无法收到回复。

查看Java代码,选项4可能对您有用,因为它正在发送消息然后关闭连接。 这段代码应该有效:

 s = socket.socket() host = socket.gethostname() # host = "192.168.0.20" port = 12345 s.bind((host, port)) s.listen(5) while True: c, addr = s.accept() # print 'Got connection from', addr message = [] chars_remaining = 8192 recv_buf = c.recv(chars_remaining) while recv_buf: message.append(recv_buf) chars_remaining -= len(recv_buf) if chars_remaining = 0: print("Exhausted buffer") break recv_buf = c.recv(chars_remaining) # print message message = ''.join(message).strip() ipAddress = addr[0]