本文介绍了Python套接字从Java PrintWriter套接字接收不完整的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I made a python "queue" (similar to a JMS protocol) that will receive questions from two Java clients. The python-server will receive the message from one of the Java clients and the second one will read the question and post an answer. The connection and messaging works, the problem comes when a Java client answers with a String of great length.

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

The response received by python is incomplete! What is worse, the message is cut at a certain number of characters and always at the same length, but, that number is different if someone else hosts the server. (i.e.: friend1 hosts the server, friend2 sends response, length received: 1380chars. Friend2 hosts the server, friend1 posts the answer, length received: 1431chars) This is the server-side python code:

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客户端:

I read questions here on StackOverflow, that c.recv() should have no problem with a big number of bytes and our response is somewhere close to 1500 characters. This is the java client:

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();
}

提前致谢!

推荐答案

从文档中:

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

Receive up to buffersize bytes from the socket. For the optional flags argument, see the Unix manual. When no data is available, block until at least one byte is available or until the remote end is closed. When the remote end is closed and all data is read, return the empty string.

所以 recv()可以返回比你要求的字节更少的字节,这就是你的情况。在中对此进行了讨论。

So recv() can return fewer bytes than you ask for, which is what's happening in your case. There is discussion of this in the socket howto.

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

Basically you need to keep calling recv() until you have received a complete message, or the remote peer has closed the connection (signalled by recv() returning an empty string). How you do that depends on your protocol. The options are:


  1. 使用固定大小的消息

  2. 有某种分隔符或标记来检测消息结束

  3. 让客户端提供消息长度作为消息的一部分

  4. 让客户端在完成发送消息后关闭连接。显然,在这种情况下它将无法收到响应。

  1. use fixed sized messages
  2. have some kind of delimiter or sentinel to detect end of message
  3. have the client provide the message length as part of the message
  4. have the client close the connection when it has finished sending a message. Obviously it will not be able to receive a response in this case.

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

Looking at your Java code, option 4 might work for you because it is sending a message and then closing the connection. This code should work:

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]

这篇关于Python套接字从Java PrintWriter套接字接收不完整的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 15:33