1

I need to connect using Java and Python sockets. I wrote code to create a server in Python and code to create a client in Java to be able to communicate between Python and Java.

The connection is created correctly, when sending data from Java to Python using writeUTF() it works, but when sending from Python and reading with java using readUTF(), I get an EOF exception. The funny thing is that if I read from Java with the readLine() method, it works.

The server code:

import socket
 
ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ser.bind(("localhost", 7000))
ser.listen(1)
 
cli, addr = ser.accept()

recibido = cli.recv(1024)
recibido = recibido.decode("UTF8")

print("Recibo conexion de la IP: " + str(addr[0]) + " Puerto: " + str(addr[1]))
print(recibido)

enviar = "hola tio".encode("UTF8")
cli.send(enviar)

cli.close()
ser.close()

print("Conexiones cerradas")

The client code:

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

public class Cliente {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket cliente = new Socket("localhost", 7000);

        DataOutputStream entrada = new DataOutputStream(cliente.getOutputStream());
        DataInputStream salida = new DataInputStream(cliente.getInputStream());

        entrada.writeUTF("Hola soy cliente");

        System.out.println(salida.readUTF());
        cliente.close();
    }
}

The exception:

Exception in thread "main" java.io.EOFException
    at java.base/java.io.DataInputStream.readFully(DataInputStream.java:202)
    at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:614)
    at Cliente.main(Cliente.java:15)
2
  • 1
    You may think your server code works with writeUTF(), but it actually doesn't (or at least, you missed the fact that the string received by the server contains two additional characters: NUL (0x00) and LF (0x10). Commented Jan 2, 2023 at 13:25
  • Nice question, as it contains all the relevant information! Commented Jan 2, 2023 at 13:27

1 Answer 1

2

You shouldn't be using a DataOutputStream/DataInputStream, it is for a particular XDR-like serialization format. The writeUTF/readUTF methods use a particular format of serialization that your Python server doesn't provide. That is they write/read 2 bytes to determine the expected length of the data, and it uses a modified UTF-8 format for the subsequent string data. Your Python server doesn't read nor write those two bytes of length (and it doesn't use the modified UTF-8 format).

As the Python server doesn't write length, the first two characters you send are interpreted as length bytes ("ho" is 0x686f or 26735), which then causes the readUTF to try and read a buffer of 26735 bytes. Given the remaining data is "la tio", or 6 bytes, this then results in the EOFException.

With the Python code as given, you should use an (optionally buffered) InputStreamReader and OutputStreamWriter configured with UTF-8. However, your protocol is deficient, because it's not possible to determine message boundaries. In the example as given that is not really relevant, as you can read until the end of input, but in general, when you need to exchange multiple messages, or a message that exceeds the length of a single TCP/IP packet, some form of message length encoding or message boundaries should be used to know when a message is complete.

Alternatively, you need to modify your Python code so it adheres to the protocol of DataOutputStream and DataInputStream. See DataOutput.writeUTF() and DataInput.readUTF() for details on the exact format.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.