2016-07-22 5 views
5

Ich versuche eine Kommunikation zwischen meiner Java-Anwendung und der relativen (in Arbeit befindlichen) iOS-Anwendung herzustellen. Nachdem Sockets geöffnet sind, schreibt die iOS-Anwendung (Client) einen "Handshake" String in den Stream und wartet dann auf den Lesestream (denke ich). Zeitgemäß öffnen Sie die Java-Anwendung (Server, vor der iOS-Anwendung gestartet) mit Erfolg den Socket und warten auf BufferedReader zum Lesen der "Handshake" und an diesem Punkt werden beide Anwendungen blockiert. Ich verstehe nicht, wie es möglich ist?TCP-Kommunikation zwischen Swift iOS und Java Sockets

Folgen Sie den Teil des iOS-Code:

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 
     } 
    } 

} 

}

Folgen Sie den Teil der Java-Code (es perfekt zwischen anderen Computern funktionieren auf die gleiche Java-Anwendung):

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... 

Wenn ich die iOS-Anwendung schließe, entsperre die Java-Anwendung vom Lesen, drucke korrekt den empfangenen Handshake und fahre dann mit seiner Arbeit fort. Jemand kann mir bitte helfen?

Antwort

2

Ich denke, Ihr Problem ist, dass Sie nie die Linie in Swift-Programm beenden.

Was readline tut gemäß BufferReader Dokumentation:

„Liest eine Textzeile eine Linie durch eine von einem Zeilenvorschub (‚\ n‘) beendet werden soll, wird in Betracht gezogen, einen Wagenrücklauf (‘. \ r '), oder ein Wagenrücklauf, unmittelbar gefolgt von einem Zeilenvorschub. "

Das bedeutet, dass entweder ein Newline-Zeichen oder das Ende der Kommunikation erwartet wird. Da Ihre Swift-Anwendung keine Zeilenschaltung sendet und den Stream nicht schließt, wartet der Client nur.

Versuchen Sie, einen Zeilenvorschub ('\ n') oder einen Wagenrücklauf ('\ r') zu setzen und zu sehen, wie es geht.

+0

Ohh Sie haben Recht !! Jetzt funktioniert es, vielen Dank! :) – sgira

+0

danke! Sehr hilfreiche Antwort! –