簡體   English   中英

使用 sockets 將 Python 服務器連接到 Java 客戶端

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

我需要使用 Java 和 Python sockets 進行連接。我編寫了在 Python 中創建服務器的代碼和在 Java 中創建客戶端的代碼,以便能夠在 Python 和 589534839 之間進行通信

正確創建連接,當使用writeUTF()從 Java 發送數據到 Python 時它工作,但是當從 Python 發送並使用 readUTF readUTF()讀取 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)

您不應該使用DataOutputStream / DataInputStream ,它適用於特定的類似 XDR 的序列化格式。 writeUTF / readUTF方法使用您的 Python 服務器不提供的特定序列化格式。 即他們寫入/讀取 2 個字節以確定數據的預期長度,並且它使用修改后的 UTF-8 格式用於后續的字符串數據。 您的 Python 服務器既不讀取也不寫入這兩個字節的長度(並且不使用修改后的 UTF-8 格式)。

由於 Python 服務器不寫入長度,您發送的前兩個字符被解釋為長度字節( "ho"是 0x686f 或 26735),然后導致readUTF嘗試讀取 26735 字節的緩沖區。 鑒於剩余數據是"la tio"或 6 個字節,這將導致EOFException

使用給定的 Python 代碼,您應該使用配置有 UTF-8 的(可選緩沖的) InputStreamReaderOutputStreamWriter 。但是,您的協議存在缺陷,因為無法確定消息邊界。 在給出的示例中,這並不是真正相關的,因為您可以閱讀到輸入結束,但一般來說,當您需要交換多條消息或超過單個 TCP/IP 數據包長度的消息時,某種形式應該使用消息長度編碼或消息邊界來了解消息何時完成。

或者,您需要修改 Python 代碼,使其遵守DataOutputStreamDataInputStream的協議。 有關確切格式的詳細信息,請參閱DataOutput.writeUTF()DataInput.readUTF()

我使用 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