Karthi Maya
Karthi Maya

Reputation: 1

TCP socket connection using CFStreamCreatePairWithSocketToHost not Working

I am new to swift Programming. I am trying to connect to a server socket from my ios app. I have a View controller and in a button action I am calling the function to connect to the socket server

let socketConn = Connection();
socketConn.connect();

I have set the delegate to self in the Connection class, but my stream function is not triggered after connecting to the server socket.

class Connection : NSObject, NSStreamDelegate {
        let serverAddress: CFString = "192.168.1.104"
        let serverPort: UInt32 = 5012

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

        func connect() {
            println("connecting...")

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

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

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

        func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
            println("stream event")
        }
    }

Can anyone help me how to debug it on why the stream function is called on connection ?

Upvotes: 0

Views: 1817

Answers (2)

Bao HQ
Bao HQ

Reputation: 1184

You can use this

import Foundation

typealias OnComing = (String!) -> (Void)

class SocketClient: NSObject, StreamDelegate {

    var host:String?
    var port:Int?
    var inputStream: InputStream?
    var outputStream: OutputStream?

    var status = false;
    var output = ""
    var bufferSize = 1024;

    var onComing:OnComing!

    func makeCFStreamConnection(host: String, port: Int, onComing:@escaping OnComing) {

        self.host = host
        self.port = port
        self.onComing = onComing

        Stream.getStreamsToHost(withName: host, port: port, inputStream: &self.inputStream, outputStream: &self.outputStream)

        if self.inputStream != nil && self.outputStream != nil {

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

            self.inputStream!.schedule(in: .main, forMode: RunLoopMode.defaultRunLoopMode)
            self.outputStream!.schedule(in: .main, forMode: RunLoopMode.defaultRunLoopMode)

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

        }


    }

    func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
        if aStream === self.inputStream {
            switch eventCode {
            case Stream.Event.errorOccurred:
                break
            case Stream.Event.openCompleted:
                break
            case Stream.Event.hasBytesAvailable:
                read()
                break
            default:
                break
            }
        } else if aStream === self.outputStream {
            switch eventCode {
            case Stream.Event.errorOccurred:
                break
            case Stream.Event.openCompleted:
                break
            case Stream.Event.hasSpaceAvailable:
                break
            default:
                break
            }
        }
    }

    func read() {
        output = ""
        var buffer = [UInt8](repeating: 0, count: bufferSize)
        while (self.inputStream!.hasBytesAvailable) {
            let bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
            if bytesRead >= 0 {
                output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: String.Encoding.ascii.rawValue)! as String
            } else {
                print("# Stream read() error")
            }
        }
        self.onComing(output)
    }

    func write(message:String) {
        let encodedDataArray = [UInt8]("\(message)\n".utf8)
        self.outputStream?.write(encodedDataArray, maxLength: encodedDataArray.count)
    }
}

Upvotes: 1

Mr. Bean
Mr. Bean

Reputation: 4281

I am using getStreamsToHostWithName function of NSStream class. It is more easy and beeter than CFStreamCreatePairWithSocketToHost

 func initNetworkCommunication() {

    print("connecting...")

    let serverAddress = "gzoa.vps.infomaniak.com"
    let serverPort = 1234

    NSStream.getStreamsToHostWithName(serverAddress, port: serverPort, inputStream: &inputStream, outputStream: &outputStream)

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

Upvotes: 1

Related Questions