通过套接字输出流从 Swift 客户端向 Java 服务器发送消息

问题描述

正如标题所说,我在仅使用本机库将 Swift 客户端连接到 Java 服务器时遇到了一些问题。

现在我有一个 Java(客户端)到 Java(服务器)的连接,它可以完美地工作,还有一个 Swift(客户端)到 Java(服务器)的连接。我的 Swift 客户端确实连接到 Java 服务器(它显示在控制台上),但我的服务器的 readFully 挂起 - 我唯一看到的是控制台上的巨大消息长度,仅此而已。

Swift 代码(发送):

func send(message: String) {
  let data = "msg:\(message)".data(using: .utf8)!

    data.withUnsafeBytes {
    guard let pointer = $0.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
      print("Error joining chat")
      return
    }
    out!.write(pointer,maxLength: data.count)
  }
}

Java 服务器(读取):

int lenght = in.readInt();
System.out.println("Message: " + lenght);
if(length>0){
 byte[] message = new byte[length];
 in.readFully(message),message.length); //This is where the problem is
}

所以,基本上Java服务器挂在readFully方法上。任何想法为什么会这样?无论我发送一个简单的 String 还是一个 Byte 数组,它总是挂起,并且由于某种原因长度非常大。有人可以帮助我了解我做错了什么,因为我已经解决了好几天了,但仍然不明白(对 Swift 来说还是很新的)。

非常感谢!

解决方法

在您的 Java 代码中,您希望前 4 个字节是消息的长度,但在 Swift 代码中,您没有先发送消息的长度。您直接发送了消息本身。所以现在 Java 代码很困惑,为什么消息比预期的要短,并等待读取更多数据。

您可以先尝试发送 data 中的字节数:

let byteCountAsByteArray = withUnsafeBytes(of: Int32(data.count).bigEndian,Array.init)
out!.write(byteCountAsByteArray,maxLength: 4)
out!.write(pointer,maxLength: data.count)

我怀疑您在 Java 代码中使用了 DataInputStream,因此是 .bigEndian。但是,如果您以小端方式阅读本文,请改用 .littleEndian