7

I created couple experiments:

Setup 1: I created a TCP Sender app and a TCP Receiver app.

For this experiment, I started the TCP Sender on an iOS device and the TCP Receiver on another iOS device. And then both are verified to have made connection and sending and received data. I then put the TCP Receiver app into background. The TCP Sender app indicated lost of connection and crashed (yes, I intended that way).

Setup 2: I created a UDP Sender app and a UDP Receiver app.

Same as above, I started the UDP Sender app on an iOS device and the UDP Receiver app on another iOS device. On the UDP Receiver app I subscribed to a multicast group, etc. I verified that the UDP Receiver app is receiving the data from that multicast group sent out by UDP Sender app. I then put the UDP Receiver app into background. After 2 minutes, I get the UDP Sender app to send out another piece of data. I then quit the UDP Sender app completely and turn off that iOS device. I then wait for another 2 minutes or more, and then bring up the UDP Receiver app from background. The UDP Receiver app did receive the data that was sent out by the UDP Sender app before it was terminated.

In setup1, my explanation is because TCP is a connection oriented.

In setup2, I understand UDP is connectionless. Any explanation why setup2 it worked the way in my experience? (Still receiving data even in background mode)

user523234
  • 14,323
  • 10
  • 62
  • 102

2 Answers2

13

All that happens when you put an app into the background and then let it go suspended is that it stops getting scheduled by the kernel. It doesn't immediately break any connections or tear down any sockets (unless you force it to.)

In your UDP case, the kernel receives the packet and puts it into a kernel buffer, waiting for your app to receive it. Since your app process exists but is effectively stopped, the data will just sit in the kernel buffer. If you get too much data, it'll overrun the kernel buffer and get dropped. Otherwise, your app can receive it when (if) it's scheduled again.

In the TCP case, pretty much the same thing hapens.

But (big but): the OS always has the option to tear down sockets for suspended apps if it wants to, based on memory pressure, etc. So while it won't necessarily do it gratuitously, it may do it.

I'm not sure exactly why you're seeing the TCP connection severed quickly. It may be that the kernel heuristics for servering TCP connections is more aggressive than for UDP sockets since TCP connections require more state and more continuous processing than do UDP sockets.

See Technical Note TN2277 Networking and Multitasking.

smparkes
  • 13,807
  • 4
  • 36
  • 61
  • 1
    By the way, I'm assuming when you say 'background' you mean 'suspended' since you didn't mention that were trying to run a background-enabled app (VOIP, music, etc.) Unless you do something special, background is a transitory state for your app which is quickly suspended after entering background. See the Apple iOS app lifecycle docs. – smparkes Jan 28 '12 at 17:41
  • Excellent explanation! My thinking was inline with your explanation and that (+1 up vote) technical article very much confirm it. Yeah, I did mean suspended not background. FYI: The reason why my TCP Sender crashed quickly because it was constantly sending stream of data to the Receiver. – user523234 Jan 28 '12 at 23:03
  • That would make sense: if you send data that the destination doesn't receive and do it with a blocking call on the main thread, iOS will see your app as not responding and kill it. The TCP connection might still be fine; it has flow control to manage buffers, but you're not allowed to block the main thread for too long. – smparkes Jan 29 '12 at 00:23
  • Great answer! It explains what I experienced in my project: I sent out data to server in appWillResignActive, and server received it immediately, and server responded immediately but the iOS app couldn't see the response immediately; after a few seconds when I brought the app back to foreground the first thing dumped in the debug log is the above mentioned response from server. However if I brought the app back to foreground after a few minutes instead of seconds, my app crashed - see "big but" in the answer. – Golden Thumb May 14 '14 at 19:27
0

My opinion is because of the os, this should not be happening if you tried on an android os because IOs has restrictions on what can work on the background and what can't.

From what you said i think its because TCP requires more resources to send information. TCP uses data streams and UDP uses data blocks. The problem is that TCP creates bigger packages of data while UDP uses 8 kb of data blocks.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215