Swift iOS和Java套接字之间的TCP通信

sgi*_*ira 7 sockets xcode ios swift

我正在尝试在我的Java应用程序和相对(正在进行中的)iOS应用程序之间建立通信.打开套接字后,iOS应用程序(客户端)将"握手"字符串写入流,然后等待读取流(我认为).当代Java应用程序(服务器,在iOS应用程序之前启动)成功打开套接字并等待BufferedReader读取"握手",此时两个应用程序都被阻止.我不明白它是怎么可能的?

按照iOS代码的一部分:

public class Client: NSObject, NSStreamDelegate  {

var serverAddress: CFString
let serverPort: UInt32 = 50000

private var inputStream: NSInputStream!
private var outputStream: NSOutputStream!
private var connecting:Bool

init(ip:String) {
    serverAddress = ip
    connecting = false

    super.init()

    connect()
}

func connect() {
    connecting = true

    while connecting {
        print("connecting...")

        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream)

        // Documentation suggests readStream and writeStream can be assumed to
        // be non-nil. If you believe otherwise, you can test if either is nil
        // and implement whatever error-handling you wish.

        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()

        self.inputStream.delegate = self
        self.outputStream.delegate = self

        self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

        self.inputStream.open()
        self.outputStream.open()

        // send handshake

        let handshake: NSData = "handshake".dataUsingEncoding(NSUTF8StringEncoding)!
        let returnVal = self.outputStream.write(UnsafePointer<UInt8>(handshake.bytes), maxLength: handshake.length)
        print("written: \(returnVal)")


        // wait to receive handshake

        let bufferSize = 1024
        var buffer = Array<UInt8>(count: bufferSize, repeatedValue: 0)

        print("waintig for handshake...")

        let bytesRead = inputStream.read(&buffer, maxLength: bufferSize)
        if bytesRead >= 0 {
            var output = NSString(bytes: &buffer, length: bytesRead, encoding: NSUTF8StringEncoding)
            print("received from host \(serverAddress): \(output)")
        } else {
            // Handle error
        }

        connecting = false

        self.inputStream.close()
        self.outputStream.close()
    }


}

public func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
    print("stream event")

    if stream === inputStream {
        switch eventCode {
        case NSStreamEvent.ErrorOccurred:
            print("input: ErrorOccurred: \(stream.streamError?.description)")
        case NSStreamEvent.OpenCompleted:
            print("input: OpenCompleted")
        case NSStreamEvent.HasBytesAvailable:
            print("input: HasBytesAvailable")

            // Here you can `read()` from `inputStream`

        default:
            break
        }
    }
    else if stream === outputStream {
        switch eventCode {
        case NSStreamEvent.ErrorOccurred:
            print("output: ErrorOccurred: \(stream.streamError?.description)")
        case NSStreamEvent.OpenCompleted:
            print("output: OpenCompleted")
        case NSStreamEvent.HasSpaceAvailable:
            print("output: HasSpaceAvailable")

            // Here you can write() to `outputStream`
            break

        default:
            break
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

}

遵循Java代码的一部分(它在使用相同Java应用程序的其他计算机之间完美地工作):

public void run()
{
    System.out.println("Server.java: waiting for connection");

    //accept
    try
    {
        serverSocket = new ServerSocket(portNumber);
        clientSocket = serverSocket.accept();
        reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

        System.out.println("Server.java: connected to " + clientSocket.getInetAddress());

        // check for input request type
        String line = reader.readLine();    // <----BLOCKED HERE!

        if(line.equals("handshake"))
        {
            connected = true;

            // send acceptation
            System.out.println("Server.java: Sending handshake, waiting response");
            writer.write("handshake");
            writer.newLine();
            writer.flush();

            // .... and the rest of code...
Run Code Online (Sandbox Code Playgroud)

当我关闭iOS应用程序时,Java应用程序从读取中解锁,正确打印收到的握手,然后继续他的工作.有人可以帮帮我吗?

Vla*_*dan 4

我认为你的问题是你永远不会结束 Swift 程序中的行。

根据 BufferReader 的文档,readLine 做了什么:

“读取一行文本。一行被视为以换行符 ('\n')、回车符 ('\r') 或回车符后紧跟换行符中的任何一个结束。”

这意味着它需要换行符或通信结束。由于您的 Swift 应用程序不会发送任何换行符并且不会关闭流,因此客户端只会等待。

尝试输入换行符('\n')或回车符('\r'),看看效果如何。