gpt4 book ai didi

java - 无法让Java和C#通过socket进行通信

转载 作者:行者123 更新时间:2023-11-30 05:52:47 24 4
gpt4 key购买 nike

我一直在尝试创建一个可以一起通信的 JavaC# 应用程序。在这种情况下,用户从C#端发送String,它应该显示在Java控制台上并回显。不幸的是,我只能建立连接,而无法发送或接收任何内容。

Java代码片段:

public CommunicationThreadHandler(Socket socket, CarList carList) {
this.socket = socket;
this.carList = carList;
try {
this.in = new DataInputStream(socket.getInputStream());
this.out = new DataOutputStream(socket.getOutputStream());
this.writer = new Writer(out);
} catch (IOException e) {
System.out.println("Exception when reading or receiving data!");
e.printStackTrace();
}
this.ip = socket.getRemoteSocketAddress().toString();
}

@Override
public void run() {
while (true) {
try {
Gson gson = new Gson();
String msgJson = in.readUTF();
String msg = gson.fromJson(msgJson,String.class);
System.out.println("Message from C# client: "+msg);
String reply = "Server echo: "+msg;
String replyJson = gson.toJson(reply);
out.writeUTF(replyJson);
if (msg.equals(Package.EXIT))
break;
} catch (IOException e) {
e.printStackTrace();
}
}

C# 代码片段:

public static void StartClient()
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];

// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);

// Create a TCP/IP socket.
Socket sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);

// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);

Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
while (true)
{
Console.Write("Enter message to server: ");

string message = Console.ReadLine();
Console.WriteLine($"To be sent: {message}");

// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes(message);

// Send the data through the socket.
int bytesSent = sender.Send(msg);

// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);

string msgFromServer = Encoding.ASCII.GetString(bytes, 0, bytesRec);

if (msgFromServer.Equals("EXIT"))
break;

Console.WriteLine($"Server says: {msgFromServer}");
}
// Release the socket.

sender.Shutdown(SocketShutdown.Both);
sender.Close();

}

最佳答案

您的问题是您在 Java 中使用 DataInputStream/DataOutputStream,它们使用 Java 特定的、类似 XDR 的数据类型序列化协议(protocol)。您没有在 C# 端使用该协议(protocol)。

切换到使用原始输入/输出流应该足够了(尽管很脆弱)。但是,请注意,当您从 C# 发送原始字节时,收件人无法得知消息何时完成。最好发送消息的字节数,然后发送实际消息(这就是 DataInputStream/DataOutputStream 所做的,但它还需要考虑其他注意事项需要在 C# 端正确实现,例如 readUTF/writeUTF 使用“修改的 UTF-8”格式而不是普通的 UTF-8。

现在的问题是,您从 C# 发送原始字节,readUTF() 方法读取前两个字节作为长度,然后尝试读取该长度的消息。例如,如果C#发送“Hello”(编码为0x48、0x65、0x6c、0x6c、0x6f),那么Java端将读取0x48、0x65(“He”)作为“消息长度为18533”,然后尝试读取18533字节,而实际剩余字节只有 3 个(“llo”)。这会导致输入阻塞,等待剩余的 18530 字节,而这些字节永远不会到达。

关于java - 无法让Java和C#通过socket进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53633327/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com