4

I'm trying to write a sample about the Bonjour service and a simple socket I/O stream.

Sample

Git URL

What I can currently do, is:

  1. Publish a service, and scan it.
  2. Create an I/O stream socket between two devices or the simulator.

After the socket is connected, I got a problem with sending text to the service.

@IBAction func sendMessage(sender:AnyObject!){

        if  (self.outputStream == nil){
            print("Connection not create yet ! =====> Return")
            return
        }

        let s : String = (self.textfield?.text)!

        print("\(self.outputStream) ==> Pass Data : \(s)")

        let data: NSData = s.data(using: String.Encoding.utf8)!

        self.outputStream?.open()
        self.outputStream?.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
        self.outputStream?.close()
        //Service no any response or log
    }

When the button's pressed, nothing seems to happen, and I'm wondering if it writes or not.

UPDATE

There was a problem with the client receiving the information. A run loop was needed.

func netService(_ sender: NetService, didAcceptConnectionWith inputStream: InputStream, outputStream: NSOutputStream) {

            self.receiveTextView?.text = "Accept Connection Success"

            print("netService : \(sender) didAcceptConnectionWith Input Stream : \(inputStream) , Output Stream : \(outputStream)")
            inputStream.delegate = self
            outputStream.delegate = self
            inputStream.schedule(in: RunLoop.main(), forMode: RunLoopMode.defaultRunLoopMode)
            outputStream.schedule(in: RunLoop.main(), forMode: RunLoopMode.defaultRunLoopMode)
            inputStream.open()
            outputStream.open()
        }

The data is then received in the Stream delegate.

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
   case Stream.Event.hasBytesAvailable:

            NSLog("HasBytesAvailable")

            var buffer = [UInt8](repeating:0, count:4096)

            let inputStream = aStream as? InputStream

            while ((inputStream?.hasBytesAvailable) != false){
                let len = inputStream?.read(&buffer, maxLength: buffer.count)
                if(len > 0){
                    let output = NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue)
                    if (output != ""){
                        NSLog("Server Received : %@", output!)
                        self.receiveTextView?.text = output as String?
                    }
                }else{
                    break
                }
            }
            break
    default:
            NSLog("unknown.")
    }

}

Webber Lai
  • 2,014
  • 5
  • 35
  • 66

1 Answers1

4

Assuming you know that the sendMessage(_:) method is getting called and all you're looking to do is check whether or not the write was successful, this can be done in a straight forward way by looking at the return value of the write method (documentation) Here's a quick example.

@IBAction func sendMessage(sender: AnyObject!) {
    guard let outputStream = outputStream else {
        print("Connection not create yet ! =====> Return")
        return
    }

    guard let text = textfield?.text,
        data: NSData = text.data(using: String.Encoding.utf8) else {
            print("no data")
            return
    }

    print("\(outputStream) ==> Pass Data : \(text)")
    outputStream.open()
    defer {
        outputStream.close()
    } 

    let result = outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
    if result == 0 {
        print("Stream at capacity")
    } else if result == -1 {
        print("Operation failed: \(outputStream.streamError)")
    } else {
        print("The number of bytes written is \(result)")
    }
}
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • Thanks , I will try your sample code now , and reply the result here . – Webber Lai Jul 12 '16 at 02:03
  • I got the log like this It seems the problem is receiver not the sender . <__NSCFOutputStream: 0x1266c5dc0> ==> Pass Data : Test The number of bytes written is 4 ,It seems success , But the service is nothing happen . – Webber Lai Jul 12 '16 at 02:34
  • Your answer can send success at a first action , but second it will always fail , I have to mark the code "outputStream.close()" , than it will success every time , why ??? – Webber Lai Jul 13 '16 at 08:29