使用套接字将Python服务器连接到Java客户端

r7knjye2  于 2023-01-04  发布在  Java
关注(0)|答案(2)|浏览(175)

我需要使用Java和Python套接字进行连接。我用Python编写了创建服务器的代码,用Java编写了创建客户端的代码,以便能够在Python和Java之间进行通信。
连接创建正确,当使用writeUTF()从Java发送数据到Python时,它工作正常,但是当使用readUTF()从Python发送数据并使用Java阅读数据时,我得到一个EOF异常。有趣的是,如果我使用readLine()方法从Java读取数据,它工作正常。
服务器代码:

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")

客户代码:

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

例外情况:

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)
7gcisfzg

7gcisfzg1#

你不应该使用DataOutputStream/DataInputStream,这是一种特殊的类似XDR的序列化格式。writeUTF/readUTF方法使用一种特殊的序列化格式,而Python服务器并不提供这种格式。也就是说,它们读写2个字节来确定数据的预期长度。它对后续的字符串数据使用修改后的UTF-8格式,Python服务器既不读取也不写入这两个字节的长度(也不使用修改后的UTF-8格式)。
因为Python服务器不写长度,所以你发送的前两个字符会被解释为长度字节("ho"是0x 686 f或26735),这会导致readUTF尝试读取26735字节的缓冲区,如果剩下的数据是"la tio",或6字节,这会导致EOFException
对于给定的Python代码,您应该使用(可选缓冲)InputStreamReaderOutputStreamWriter配置为UTF-8。但是,您的协议有缺陷,因为它无法确定消息边界。在给出的示例中,这并不真正相关,因为您可以读取到输入结束,但通常情况下,当您需要交换多个消息时,或超过单个TCP/IP分组长度的消息,则应当使用某种形式的消息长度编码或消息边界来知道消息何时完成。
或者,您需要修改Python代码,使其符合DataOutputStreamDataInputStream协议。有关确切格式的详细信息,请参见DataOutput.writeUTF()DataInput.readUTF()

qyyhg6bp

qyyhg6bp2#

我使用BufferedWriter和BufferedReader进行修复。

BufferedWriter entrada = new BufferedWriter(new OutputStreamWriter(cliente.getOutputStream()));
BufferedReader salida = new BufferedReader(new InputStreamReader(cliente.getInputStream()));

相关问题