Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how connect to socket in swift to read data and write it

Tags:

swift

sockets

how to create a socket in swift that listen to and write on it? Is GCDAsyncSocket a right way or another way is possible? I used CFStreamCreatePairWithSocketToHost to connect to socket but can not read data from.

like image 770
user2056962 Avatar asked Feb 15 '15 08:02

user2056962


People also ask

How do I connect sockets in Swift?

First, we need to create a Socket class: Create a class (I called it SocketServer), this class is going to connect to the desired socket using host & port . Later on, we're going to declare a protocol ( SocketDelegate ) that this class calls its methods when InputStream has available response.

What is connect in Socket?

The connect() call on a stream socket is used by the client application to establish a connection to a server. The server must have a passive open pending. A server that is using sockets must successfully call bind() and listen() before a connection can be accepted by the server with accept().

How does Socket work in iOS?

The socket communication relies on the client-server logic, where a persistent connection between a server and a client always exists. To be more precise, the server “opens” a dedicated port where clients get connected to it.


1 Answers

For those who are interested for a Swift 3 implementation. It's referenced heavily from raywenderlich's example with some edits.

func connect() {
    Stream.getStreamsToHost(withName: self.address!, port: self.port!, inputStream: &self.inputStream, outputStream: &self.outputStream);

    guard let _ = inputStream, let _ = outputStream else {
        // your own execption or otherwise
        return;
    }

    self.inputStream?.delegate = self;
    self.outputStream?.delegate = self;

    self.inputStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode);
    self.outputStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode);

    self.inputStream?.open();
    self.outputStream?.open();
}

func disconnect() {
    if let stream = self.inputStream {
        stream.close();
        stream.remove(from: RunLoop.current, forMode: RunLoopMode.commonModes);
    }
    if let stream = self.outputStream {
        stream.close();
        stream.remove(from: RunLoop.current, forMode: RunLoopMode.commonModes);
    }
    self.inputStream = nil;
    self.outputStream = nil;
}

func write(data:Data) {
    let _ = data.withUnsafeBytes { (unsafePointer:UnsafePointer<UInt8>) in
        let bytesWritten = self.outputStream?.write(unsafePointer, maxLength: data.count);
    };
}

func readAvailableBytes(stream: InputStream) {
    var buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: maxReadLength);
    while stream.hasBytesAvailable {
        let numberOfBytesRead = stream.read(buffer, maxLength: maxReadLength)
        if numberOfBytesRead < 0 {
            if let _ = stream.streamError {
                break
            }
        }
        //Construct the Message object
        if(numberOfBytesRead > 0){
            let output = String(cString:buffer)
            NSLog("server said: %@", output)
        } else {
            NSLog("empty string from stream")
        }

    }
    buffer.deallocate(capacity: maxReadLength);
}

And be sure to implement StreamDelegate and the delegate method in your handling class:

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    NSLog("Receieve stream event: %d", eventCode.rawValue);
    switch (eventCode){
    case Stream.Event.errorOccurred:
        NSLog("ErrorOccurred")
        break;
    case Stream.Event.endEncountered:
        NSLog("EndEncountered")
        break;
    case Stream.Event.hasBytesAvailable:
        NSLog("HasBytesAvaible");
        break;
    case Stream.Event.openCompleted:
        NSLog("OpenCompleted");
        break;
    case Stream.Event.hasSpaceAvailable:
        NSLog("HasSpaceAvailable");
        break;
    default:
        NSLog("default reached. unknown stream event")
        break;
    }
} 

Note: There are some changes from raywnderlich's implementation, particularly in the delegate method.

like image 172
Sev Avatar answered Sep 27 '22 19:09

Sev