简体   繁体   English

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

[英]Connect an Python server to Java client with sockets

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.我需要使用 Java 和 Python sockets 进行连接。我编写了在 Python 中创建服务器的代码和在 Java 中创建客户端的代码,以便能够在 Python 和 589534839 之间进行通信

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.正确创建连接,当使用writeUTF()从 Java 发送数据到 Python 时它工作,但是当从 Python 发送并使用 readUTF readUTF()读取 java 时,我得到一个 EOF 异常。 The funny thing is that if I read from Java with the readLine() method, it works.有趣的是,如果我使用 readLine() 方法从 Java 读取数据,它就可以工作。

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)

You shouldn't be using a DataOutputStream / DataInputStream , it is for a particular XDR-like serialization format.您不应该使用DataOutputStream / DataInputStream ,它适用于特定的类似 XDR 的序列化格式。 The writeUTF / readUTF methods use a particular format of serialization that your Python server doesn't provide. writeUTF / readUTF方法使用您的 Python 服务器不提供的特定序列化格式。 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.即他们写入/读取 2 个字节以确定数据的预期长度,并且它使用修改后的 UTF-8 格式用于后续的字符串数据。 Your Python server doesn't read nor write those two bytes of length (and it doesn't use the modified UTF-8 format).您的 Python 服务器既不读取也不写入这两个字节的长度(并且不使用修改后的 UTF-8 格式)。

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.由于 Python 服务器不写入长度,您发送的前两个字符被解释为长度字节( "ho"是 0x686f 或 26735),然后导致readUTF尝试读取 26735 字节的缓冲区。 Given the remaining data is "la tio" , or 6 bytes, this then results in the EOFException .鉴于剩余数据是"la tio"或 6 个字节,这将导致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.使用给定的 Python 代码,您应该使用配置有 UTF-8 的(可选缓冲的) InputStreamReaderOutputStreamWriter 。但是,您的协议存在缺陷,因为无法确定消息边界。 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.在给出的示例中,这并不是真正相关的,因为您可以阅读到输入结束,但一般来说,当您需要交换多条消息或超过单个 TCP/IP 数据包长度的消息时,某种形式应该使用消息长度编码或消息边界来了解消息何时完成。

Alternatively, you need to modify your Python code so it adheres to the protocol of DataOutputStream and DataInputStream .或者,您需要修改 Python 代码,使其遵守DataOutputStreamDataInputStream的协议。 See DataOutput.writeUTF() and DataInput.readUTF() for details on the exact format.有关确切格式的详细信息,请参阅DataOutput.writeUTF()DataInput.readUTF()

I repair using BufferedWriter and BufferedReader.我使用 BufferedWriter 和 BufferedReader 进行修复。

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

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

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