简体   繁体   English

Java客户端和python服务器套接字连接-接收消息时文件结束错误

[英]Java client and python server socket connection - end of file error when receiving message

I need to send a message from a java client program to a python server program.我需要从 java 客户端程序向 python 服务器程序发送消息。

Here is my code:这是我的代码:

Java client: Java客户端:

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        // need host and port, we want to connect to the ServerSocket at port 7777
        Socket socket = new Socket("localhost", 7777);
        System.out.println("Connected!");

        // get the output stream from the socket.
        OutputStream outputStream = socket.getOutputStream();
        // create a data output stream from the output stream so we can send data through it
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

        System.out.println("Sending string to the ServerSocket");

        // write the message we want to send
        dataOutputStream.writeUTF("Hello from the other side!");
        dataOutputStream.flush(); // send the message
        dataOutputStream.close(); // close the output stream when we're done.

        System.out.println("Closing socket and terminating program.");
        socket.close();
    }
}

Python server:蟒蛇服务器:

from multiprocessing.connection import Listener
address = ('localhost',7777)
while True:
    with Listener(address, authkey=None) as listener
        with listener.accept() as conn:
            print(conn.recv())

When I try to execute this, I get the following error in Python:当我尝试执行此操作时,在 Python 中出现以下错误:

OSError: got end of file during message

What am I doing wrong?我究竟做错了什么?

Use of the multiprocessing module seems inappropriate in this case and is the root cause of your problem.在这种情况下,使用 multiprocessing 模块似乎不合适,并且是问题的根本原因。 Here's a simplified Python server that demonstrates how you could achieve your objective.这是一个简化的 Python 服务器,它演示了如何实现您的目标。 Note that the server terminates after accepting and handling any single connection:请注意,服务器在接受并处理任何单个连接后终止:

import socket

def server():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('0.0.0.0', 7777))
        s.listen()
        conn, _ = s.accept()
        with conn:
            while (data := conn.recv(8192)):
                print(data.decode())

if __name__ == '__main__':
    server()

The issue here is that the recv* functions of the multiprocessing connection expect to get a 32-bit preamble in the message that indicates the actual amount of data being transmitted.这里的问题是多处理连接的 recv* 函数期望在消息中获得一个 32 位的前导码,指示正在传输的实际数据量。 So here's what the Java part needs to look like (I haven't bothered about buffered IO - just keeping things to bare bones):所以这就是 Java 部分需要的样子(我没有担心缓冲 IO - 只是保持简单):

import java.io.IOException;
import java.net.Socket;
import java.io.OutputStream;

public class Client {

    public static void main(String[] args) throws IOException {
        try (Socket socket = new Socket("localhost", 7777)) {
            OutputStream out = socket.getOutputStream();
            byte[] dts = "Hello from the other side!".getBytes();
            out.write(net(dts.length));
            out.write(dts);
        }
    }
    private static byte[] net(int n) {
        byte[] buffer = new byte[4];
        for (int i = 3; i >= 0; i -= 1) {
            buffer[i] = (byte)(n & 0xff);
            n >>>= 8;
        }
        return buffer;
    }
}

Then, your Python server can look something like this:然后,您的 Python 服务器可能如下所示:

from multiprocessing.connection import Listener

def main():
    listener = Listener(address=('0.0.0.0', 7777), family='AF_INET', authkey=None)
    with listener.accept() as conn:
        print(conn.recv_bytes().decode())
            

if __name__ == '__main__':
    main()

So, this means that your original problem is due to recv() looking at the first 4 bytes and interpreting that as the length of incoming data.因此,这意味着您的原始问题是由于 recv() 查看前 4 个字节并将其解释为传入数据的长度。 But that would equate to something much larger than was actually being sent.但这相当于比实际发送的要大得多的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM