IOS And AsyncUDPSocket - Tutorial? - ios

I am learning C and Objective-C so am still dependent on examples...
I found AsyncUDPSocket which has a lot of example code in the Google Code repository, but I'm not far enough along to understand it all yet.
I'm trying to build an iPhone app that uses UDP for communication to another device (Arduino). I have the device end working (testing with the UDP Tool app). I just need help with the iOS side of it...
An example with more explanation would really help (that is, a tutorial)... Is there one or what would some example code with good comments be?

https://github.com/robbiehanson/CocoaAsyncSocket
GCDAsyncUdpSocket and AsyncUdpSocket are UDP/IP socket networking libraries. Here are the key features available in both:
Native objective-c, fully self-contained in one class. No need to
muck around with low-level sockets. This class handles everything for
you.
Full delegate support.
Errors, send completions, receive completions, and disconnections all result in a call to your delegate method.
Queued non-blocking send and receive operations, with optional
timeouts.
You tell it what to send or receive, and it handles everything for you. Queueing, buffering, waiting and checking errno - all
handled for you automatically.
Support for IPv4 and IPv6.
Automatically send/recv using IPv4 and/or IPv6. No more worrying about multiple sockets.

Related

alternative for deprecated CFStreamCreatePairWithSocket

The Apple docs mark CFStreamCreatePairWithSocket as deprecated since IOS 15.0.
What would be a related successor ?
We use CFSocket/NSStream functions currently to have event driven network reads/writes in a runloop.
For the record, we ended up rewriting our code to use plain Berkeley sockets together with the GCD dispatch_source machinery ... there is a working socket server sample not triggering the local network prompt at
https://github.com/leopatras/GCDSimpleSocketServer/
The dispatch_source_zzz functions allow a similar event driven approach like the CFStreamCreatePairWithSocket function (and even less code).
See https://github.com/leopatras/cfsocket for comparison with the old CFSocket stuff.
As this is anyway deprecated and triggers the local network prompt in some situations: don't use it anymore.
I had an intensive exchange with the Apple support about this topic, they did recommend using the new Network framework functions instead of Berkeley sockets (See https://developer.apple.com/documentation/network?language=objc) and I tried hard to use them however I failed to create a simple reliable working echo server with those functions in obj-C (didn't try the Swift route).

Bonjour/NSNetService Data written to NSOutputStream never makes it to the other side (includesPeerToPeer = true)

I have an iOS app that establish a peer-to-peer connection through Bonjour/NSNetService. (based on the WiTap sample code)
In some cases, both devices won’t receive data anymore after a few seconds while they are still able to write data out (i.e. without an error being reported).
The data written to the NSOutputStream never makes it to the NSInputStream of the other side.
The strange part is that sending and receiving works right after the connection is established. It seems to go bad after a few seconds.
If I set includesPeerToPeer = false it is not happening anymore. Does anyone having the same issue? I need to use peer to peer because is required to use bluetooth.
Thanks
My first guess would be that you're writing data to the stream before you get a stream event telling you that it is ready to accept more data.
If that isn't the problem, then either it's a bug in your code (which you haven't posted any of) or... well, it is possible that the class in question still doesn't work correctly. See:
https://developer.apple.com/library/ios/qa/qa1546/_index.html
If that's the case, you might have to drop down to Core Foundation briefly.

Raknet connection issue on Unity3D + iOS (il2cpp)

I have weird issue running the last version of Raknet on iOS with Unity3D: I get CONNECTION_ATTEMPT_FAILED when trying to connect to the server.
Now let's me detail the issue:
he exact same Library connects fine when used in an ObjectiveC application, so the issue seems to be Unity3D related.
I already managed to pinpoint my issue to be located in Raknet reliability layer:
Apparently, during the last step of the connection process (when the connection handshake as been completed) the reliability layer of the server thinks that the ID_CONNECTION_REQUEST packet received from the client is an acknowledgment instead of a message. Therefore it doesn't answer. Ultimately after a few tries, (and a 10s timeout) the client fails with the CONNECTION_ATTEMPT_FAILED error.
Does anybody there as an idea? I will update the question when I manage to get more info.
Update
We are using Unity3D 5.1.1f1
We managed to find a workaround! See answer for more information. As the workaround doesn't tell us much about what really happened, I would gladly hear some C++/XCode/Unity/iOS/AppleLLVM6.1 experts around here explain what really happened.
The issue was that the Raknet header wasn't properly generated by the iOS client. Namely we were sending ACK messages in place of simple packets. The rest of the message was considered as garbage by the server and the packet was dropped. The client kept trying to send the corrupted handshake packet a few times before timeouting.
This doesn't tell us why, doesn't it? Apparently the serialize method of the class DatagramHeaderFormat wasn't called as it should have been when running Raknet in Unity (iOS). Something else (and I don't know what) was linked in place of this method and was filling the BitStream with a corrupted header.
I am quite sure that the serialize method wasn't called because printf calls from inside weren't displayed in the console.
We renamed DatagramHeaderFormat::serialize into DatagramHeaderFormat::serializeHeader and... voila, it works.
Now I only want to understand what did the compiler (and why).

What is the real necessity of Apple's Reachability framework?

I have read up on the Reachability framework and am still confused why the definition of a host is being reachable is "when a data packet... can leave the local device".
If reachability returns "yes" then it seems that I still need to try and make a socket connection and until that actually connects I do not really know my host is up. Why doesn't Reachability use a Ping to get a better idea of whether the host is actually up? And what is the need of this framework in the first place?
My guess is these two, but if anyone knows any other reasons to use the Reachability framework please let me know.
1) Reachability gives a callback which gives instant notification when the internet comes back up. When this occurs a socket connection can be immediately attempted. However in 99% of applications it seems acceptable to just attempt a socket connection every few seconds, or worst case just try to make the connection when a user does a certain action. Granted, this is not an ideal solution but I don't see why the Reachability framework would ever be really necessary for this reason.
2) Even in the case where a socket connection has been made to the server, Reachability gives an important bit of information about whether the network is G3/WiFi. I think this is the only time Reachability is really necessary because it allows optimization of behavior according to network type.
Reachability is actually quite useful: Given your case (1), you forget that it gives you notifications on both network up and down events. Meaning you can set the callback to handle events such as losing network connectivity (which happens more than you would like on both WiFi and 3G).
Additionally, testing a connection using a socket is not that straightforward; Socket operations are , by default, blocking, and though you can use asynchronous operations (or threads), doing so involves writing code. Not to mention trying DNS when the network is down, and other such issues. By setting a reachability target using the framework, you can alleviate the need to handle all sorts of issues like these yourself, and simply wait for that callback.
Hope this helps,
TG

Swizzling low-level TCP methods on IOS

I am trying to find a way to get information on all the TCP traffic to and from my IOS application. The application is very simple and composed of a single UIWebView object.
I tried to use swizzling on NSURLRequest but didn't have much luck with that - my version of requestWithURL: is called when I call it NSURLRequest manually, but it doesn't seem to ever be called when going to a page in UIWebView, so I guess its using a different object under the covers.
So I thought of trying to hook into CFSocket functions, but those are not part of a class so I'm not sure how to swizzle them (or if its even possible).
Are there any ways to hook into C functions on IOS, or any other APIs I can try to swizzle to access TCP (or even HTTP) traffic?
I also tried using NSURLCache, which works for most of the main .html pages, but as many people have found out the .cs files and some others don't seem to go through the cache.
Thanks!
Just set up an external proxy like Fiddler or Charles to monitor http traffic. Or more complicated, Wireshark for any tcp traffic. This will be much easier than what you're trying and more powerful.

Resources