简体   繁体   中英

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.

Here is my code:

Java client:

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:

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. Here's a simplified Python server that demonstrates how you could achieve your objective. 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. So here's what the Java part needs to look like (I haven't bothered about buffered IO - just keeping things to bare bones):

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:

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. But that would equate to something much larger than was actually being sent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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