I’m trying to add some simple peer-to-peer connection functionality to an iOS library. Coding for outgoing connections was simple enough; a call to CFStreamCreatePairWithSocketToHost connects to a remote host and sets up streams for reading/writing from/to it. Simple enough.
However, I couldn’t find an equivalently easy way to set up a socket to listen for/accept incoming connections. So I went back to basics and used socket(), bind(), listen(), and accept() to implement low-level connection handling, patterned largely after the example here:
http://www.pcs.cnu.edu/~dgame/sockets/server.c
That’s all fine, but now that I’m able to accept incoming connections I’m wondering how to go about creating CFReadStream and CFWriteStream instances to manage them. Is there a straightforward way of doing so?
As an aside, I’m aware that a CocoaAsyncSocket library exists that supports asynchronous server sockets, but I’m really not interested in an async solution.
Okay, turns out that the answer was actually fairly simple. You can use:
…to bind a
CFReadStreamandCFWriteStreamto an already connected socket. That flow seems a little backwards to me (i.e. what if bytes have already been read from the socket, etc., and why isn’t it possible to just bind something to the listening/server socket such that every time a new connection is accepted correspondingCFReadStreamandCFWriteStreaminstances are automatically set up?), but whatever.The code goes like:
So the important things to realize were:
It’s not necessary to bind anything to the socket you are listening on; instead it’s possible to bind
CFReadStreamandCFWriteStreaminstances arbitrarily to any already connected socket, even if you’ve already read/written data from/to it.For all its fancy verboseness, a
CFSocketNativeHandleis just anint. Oh how I loathe unnecessary aliasing of primitive types to things that sound like they aren’t primitive types.