我一直在尝试创建一个可以相互通信的 Java 和 C#应用。在这种情况下,用户从 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();
}
答案 0 :(得分:1)
您的问题是您在Java中使用DataInputStream
/ DataOutputStream
,这些语言使用了特定于Java的类似XDR的数据类型序列化协议。您没有在C#端使用该协议。
切换到使用原始输入/输出流应该足够了(尽管非常脆弱)。但是,请注意,当您从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字节,这些字节永远不会到达。