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

时间:2014-11-28 04:07:13

标签: java python sockets 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();
}

提前致谢!

1 个答案:

答案 0 :(得分:1)

来自文档:

  

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

     

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

因此recv()可以返回比您要求的更少的字节数,这就是您的情况下发生的事情。 socket howto对此进行了讨论。

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

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