We have been using the AsyncSocket library EXTENSIVELY here at deusty. We use it as the basis for our Open Source Embedded HTTP Server, and we also use it within our XMPP client, and within our STUNT (TCP NAT Traversal) code.
Over time, we've grown to love this little class, but that's not to say we didn't run into a few bugs. We've squashed a few, added a few features, and many comments. We're calling our latest version AsyncSocket 4.3.4 and you can download it here:
CHANGES IN VERSION 4.3.1:
If user called acceptOnPort:0, then the OS would automatically pick a port for you. This is what is supposed to happen, except that it would pick a different port for IPv4 and IPv6. Added code to make sure both protocols are listening on the same port
Added comments in many places
Altered bits of code to match Apple's coding style guidelines
Renamed method "attachAcceptSockets" to "attachSocketsToRunLoop:error:"
CHANGES IN VERSION 4.3.2
Removed polling - it's not needed
Added another delegate method: onSocket:didReadPartialDataOfLength:tag:
Often, when using the AsyncSocket class, it was important to display a progress bar to the user. This was possible using Timers, and calling progressOfRead, but it wasn't the easiest solution. This delegate method will allow for automatic notification when using readToLength: or readToData:
CHANGES IN VERSION 4.3.3
The methods connectedHost, connectedPort, localHost, and localPort all assumed IPv4 connection. In other words they all assumed theSocket was valid, causing a crash when the OS connected via IPv6. Updated all methods to properly check either theSocket or theSocket6.
In the doStreamOpen method, there was an assumption that IPv4 was used and thus a valid theSocket variable. This was not always the case, causing this to fail:
Fixed the problem by simply using the connectedHost and connectedPort methods.
Added safety check in addressPort: method:
if (cfaddr == NULL) return 0;
The kCFStreamPropertyShouldCloseNativeSocket was previously getting set in the configureStreamsAndReturnError: method. This may have been OK, but it would have caused a problem if the following sequence occurred:
A socket was accepted and doAcceptWithSocket: method was called,
This method then encoutered an error while attaching the streams to the run loop.
If this sequence happened, the BSD socket would not have been closed.
So I moved this into the createStreams... methods.
CHANGES IN VERSION 4.3.4
In doReadTimeout: the code properly calls endCurrentWrite and then closes with an error.
In doWriteTimeout: the code was calling completeCurrentWrite and then closes with an error.
This resulted in the delegate being told that his write completed (when it didn't)
immediately prior to disconnecting with an error.