I know that you can create a NSInputStream
and NSOutputStream
pair (toll-free bridged to CFReadStream
, CFWriteStream
) by opening a TCP client connection using CFStreamCreatePairWithSocketToHost
according to the Stream Programming Guide.
How can one create a TCP server that listens on a port and accepts a connection as a NSInputStream
and NSOutputStream
pair?
The RemoteCurrency sample project provides an example of this in QServer.m (previously known as TCPServer.m). The sample code is actually for setting up Bonjour advertising, but that part can be excluded for a simple TCP server.
You create a socket with your own accept callback by calling CFSocketCreate
, bind and listen to a port by calling CFSocketSetAddress
, and start getting accept callbacks by calling CFSocketCreateRunLoopSource
followed by CFRunLoopAddSource
.
Then, in the accept callback, you create NSInputStream
/NSOutputStream
pair from the connection handle using CFStreamCreatePairWithSocket
, set the input stream’s delegate and start receiving recv callbacks by calling scheduleInRunLoop:forMode:
, and then open
both streams to start using them.
Using NSInputStream and NSOutputStream abstractions (as opposed to creating a new thread and calling the standard UNIX functions socket
, bind
, listen
, accept
, send
, recv
) allows one to easily receive network events in the same NSRunLoop as the rest of the run-loop based APIs on OSX.