How do you keep iOS from clustering TCP packets when trying to send data - ios

I am writing a real-time game client. It works great on desktop, but as I come to implement it on iOS, the packets seems to cluster together and only send ever half second to 1 second which yields a very jumpy experience.
I am using the low level sys/socket library so a send simply looks like
send(this->sock, bytes, byteslength, 0)
As I said, this does not have this behavior on a desktop system, but I assume there is some sort of power saving logic going on here that wants to cluster the data into a single packet instead of sending the packet as soon as send is called. Certainly there must be a way to force the fast send.

Related

Is it possible to setup timeout for receiving data over USB in STM32 MCUs?

I'm wondering if this is possible to setup a timeout for receiving data over USB interface in STM32 microcontrollers. Such approach is possible for example in UART connection (please refer to AN3109, section 2. Receive DMA timeout).
I can't find anything similar related to USB interface. What's more, it is said that DMA for USB should be enabled only if really necessary because data transfer shall be aligned to 32-bit word.
You have a receive call back function (if you use the HAL) in your ...._if.c file. Copy reived chars to the buffer. Implement timeout there.
What you refer to in case of UART is either DMA receive timeout as you've said or (when not using DMA) an IDLE interrupt. I'm not aware of such thing coming "out of the box" for USB CDC - you'd have to implement this timeout yourself, which shouldn't be too hard. Have a timer (hardware of software) that you re-trigger every time you receive data. Set its period to the timeout value of your choice and do protocol parsing after timeout elapses.
If I had to add anything - these kind of problems (not knowing how many bytes to receive) are typically solved at the protocol level. Assuming binary protocol, one way of achieving this is having frame start and end bytes which never occur in data (and if they do - you escape them) in which case you receive everything starting after "start byte" until you reveive "end byte". Yet another way is having a "start byte" and a field indicating how many bytes there are to receive. All of it should of course be checksumed in some way.
Having said that, if you have an option to change the protocol, you really should do so. Relying on timings in your communication, especially on such low level only invites problems and headaches in the long run. You introduce tight coupling between your protocol layer and interface layer. This is going to backfire on you every time you decide to use a different interface, as you'll have to re-invent the same thing again. Not to mention how painful it's going to be when you decide to move to TCP/IP with all its greatness - network jitter, dropped packets etc.

Google Nearby connections - Not able to transfer large bytes between 2 devices

When I try to send an object with multiple images(converted to string using Base64) as STREAM type, from the onPayloadTransferUpdate() method, I can see "Failure" result and the devices(tested only when 2 devices are connected) automatically disconnect after that. Is Google Nearby connections not the right option to send large bytes?
Nearby Connections should be able to handle that. There's no explicit size limit on STREAM payloads.
I would suggest chunking the bytes (eg. send a couple KB at a time) and seeing if that helps. You can get into weird situations when you send entire files at once because it loads the bytes into memory twice (once inside your app, and once inside the Nearby process) which can cause out of memory errors. Binder, the interprocess communication layer on Android, also has a limited buffer to send data between processes.
You can also save it as a temporary file and send it as a FILE payload, in which case we will handle the chunking for you.
Disclaimer: I work on Nearby Connections.
1) You don't need to Base64-encode the data for the sake of Nearby Connections -- your STREAM can have raw binary data, and that'll work just fine.
2) How big is this data you're sending, and at what byte offset (you can see this in the PayloadTransferUpdate you get with Status.ERROR) does it fail at? It sounds like your devices are just getting disconnected.
3) What Strategy are you using?
4) If you still have discovery ongoing (i.e. you haven't called stopDiscovery()), try stopping that and then sending your Payload -- discovery is a heavyweight operation that can make it hard to reliably maintain connections between devices for long intervals.

Corebluetooth terminate large data transfer without terminate bluetooth connection

I am developing an app that needs to send large amounts of data between an iPhone and a device (it takes approximately 10 seconds to send the data). But I want to be able to cancel the data communication anytime. I am aware I can simply drop the connection to the device at anytime with
centralManager.cancelPeripheral(peripheral)
but that is not what I am actually looking for, as I want to stop sending data but without terminating the bluetooth connection.
Is there a way to terminate the data transmission without dropping the connection to the device?
the codes of sending data is as follow:
for (var Hex: UInt8 = 0x01; Hex <= 0x14; Hex+=1){
var outbuffer = [UInt8](count: 16, repeatedValue: 0x00)
outbuffer[0] = (0x68)
outbuffer[1] = (Hex)
let data = NSData(bytes: outbuffer, length: 7)
print("data\(data)")
connectingPeripheral.writeValue(data, forCharacteristic: connectingCharacteristicPassword , type: CBCharacteristicWriteType.WithResponse)
}
I figured that I would go ahead and give my input on this. There is no way in CoreBluetooth to stop the transmission of a data packet that has already been written to the output buffer. The reason for why this is the case is simply because it is not needed and it would be a useless functionality. The only reason for why you are having this issue is because your methodology is wrong in my opinion. Do not put everything in a for-loop and push the data all at once. Instead you should implement some sort of flow control mechanism.
In Bluetooth LE there are two main ways of writing data to a peripheral: “Write Commands” and “Write Requests”. You can look at it a bit like the TCP vs UDP protocols. With write commands you are just sending data without knowing whether or not the data was received by the application on the other side of the bluetooth link. With write requests you are sending data and letting the peripheral know that you want to be notified (ack’ed) that the data was in fact received. These two types are in CoreBluetooth called CBCharacteristicWriteWithResponse and CBCharacteristicWriteWithoutResponse. When writing data using the CBCharacteristicWriteWithResponse (like you are doing in your code) you will get a peripheral:didWriteValueForCharacteristic:error: callback which verifies that the data has arrived at the other side. At this point you now have the option to go ahead and send the next packet if you want to, but if you for some reason want to stop sending data, then you can do that as well. Doing it this way you are in control of the whole flow and not just simply pushing everything though a for-loop.
But wait, why would you ever want to use write commands then? Well, since write requests requires the receiver to respond back to the sender it means that data must be sent in both directions. In this case, since the ack is sent by the application layer, you have to wait for the next connection interval before the ack can be sent. This means that when sending large amounts of data you can only send one packet per every two connection intervals which will give you a very poor overall bit rate.
With write commands, since they are not ack’ed, you can send as manny packets as possible within one connection event window. In most cases you should be able to send about 10-20 packets per connection window. But be aware that if you send too many packets then you will fill the outgoing buffer and packets will be lost. So, something that you can try is to directly send 9 packets with the WriteWithoutResponse type, followed by 1 packet of the WriteWithResponse type. After doing this you can wait for the peripheral:didWriteValueForCharacteristic:error: callback in which you can then send 10 more packets the same way. This way you will manage to send 10 packets per every 2 connection intervals while still being able to control the flow better.
You can of course experiment with the ratio a bit, but remember that the buffer is shared between multiple applications on the iOS device so you don’t want to be too close to the limit.

UDP vs TCP for non-frequent input based game

I was reading the article on gafferon about network programming, and it explains the advantages and disadvantages of UDP vs TCP.
However, It feels like that only works for a game that requires constant streams of input. I'm developing a card game, and I was wondering what would be the most effective way to create the multiplayer features, UDP or TCP. I feel like UDP is probably still the best pick just for its speed, but that raises further questions.
If I use UDP, on the low chance that a packet gets loss, how do I know it got lost and how do I recover from the loss?
How to detect the loss of a message?
The receiver needs to send something back to the original sender that tells him it received the message. If the original sender gets no acknowledgement during a defined timeframe, it will resend the message.
Another method is to send each message multiple times per default and let the receiver ignore duplicates.
The rules for this can get arbitrarily complex and in the end you'll reimplement parts of TCP. You might also want to ensure ordering of the messages.
UDP is good for frequent updates where it's not that bad to lose some messages (e.g. delivering a video stream or keeping player positions in sync in a first person shooter). A card game is slower-paced but requires reliable, ordered messages. If you don't plan to host game sessions with multiple thousands of players, use TCP. It's fast enough and much easier to work with.
It only works with constant streams of input?
TCP works fine even if you only send one message every minute. The term "stream oriented" basically means that the receiver doesn't know where a message ends. You'll have to provide that information in your protocol by prepending the message length for example.
If you choose UDP you'd be better off using a library on top of it.

What kind of socket server protocol is efficient?

When I was writing a simple server for a simple client <> server multiplayer game, I thought of the following text-based protocol using a translation library. Basically, each command had a certain meaning, eg:
1 = character starts turning right
2 = character starts turning left
3 = character stops turning
4 = character starts moving forward
5 = character stops moving
6 = character teleports to x, y
So, the client would simply broadcast the following to inform that the player is now moving forward and turning right:
4
1
Or, to teleport to 100x200:
6#100#200
Where # is the parameter delimiter.
The socket connection would be connected to the player identifier, so that no identifier has to be broadcasted with the protocol to know what player the message belongs to.
Of course all data would be validated server side, but that is a different subject.
Now, this seems pretty efficient to me, only 2 bytes to inform the server that I am moving forward and turning right.
However, most "professional" code snippets I saw seemed to be sending objects or xml commands. This seems to require a lot more server resources to me, doesn't it?
Is my unexperienced logic of why my text based protocol would be efficient flawed? Or what is the recommended protocol for real-time action multiplayer games?
I want to setup a protocol that is as efficient as possible, because I do not want to use multiple clusters/servers to cover excessive amounts of bandwidth for my 2D multiplayer game, and to safe synchronization problems and hassle.
However, most "professional" code
snippets I saw seemed to be sending
objects or xml commands. This seems to
require a lot more server resources to
me, doesn't it?
Is my unexperienced logic of why my
text based protocol would be efficient
flawed? Or what is the recommended
protocol for real-time action
multiplayer games?
Plain text is more expensive to send than a binary format containing the same information. For example, if you only send 1 byte, you can only send 10 different commands, digits 0 to 9. A binary format can send as many different commands as there are different values you can fit into a byte, ie. 256.
As such, although you are thinking of objects as being large, in actual fact they are almost always smaller than the plain text representation of that same object. Often they are as small as is possible without compression (and you can always add compression anyway).
The benefits of a plain text format are that they are easy to debug and understand. Unfortunately you lose those benefits if you put your own encoding in there (eg. reducing commands down to single digits instead of readable names). The downside is that the format is bigger, and that you have to write your own parser. XML formats eliminate the second problem, but they can't compete with a binary format for pure efficiency.
You are probably overthinking this issue at this stage, however. If you're only sending information about events such as the commands you mention above, bandwidth will not be a concern. It's broadcasting information about the game state that can get expensive - but even that can be mitigated by being careful who you send it to, and how frequently. I would recommend working with whatever format is easiest for now, as this will be the least of your problems. Just make sure that your code is always in a state where you can change the message writing and reading routines later if you need.
You need to be aware of the latency involved in sending your data. "Start turning"/"stop turning" will be less effective if the time between the receipt of those packets is different than the time between sending them.
I can't speak for all games, but when I've worked on this sort of code we'd send orientation and position information across the wire. That way the receiver could do smoothing and extrapolation (figure out where the object should be "now" based on data that I have that is already known to be old). Different games will want to send different data, but generally speaking you will need to figure out how to make the receiver's display of the data match the sender's, so you'll need to send data that is resilient in the face of networking problems.
Also, many games use UDP for this sort of data transfer instead of TCP. UDP is unreliable, so you may not get all of your packets. That means that "stop moving now" or "start moving now" may not be received in pairs. When coding on top of UDP then it's even more important to send "this is the state right now" every so often so that clients get ample opportunity to sync up.
The common way is to use a binary format, not text, not xml. So with only one byte you can represent one of 256 different commands.
Also use UDP and not TCP. The game will be a lot more responsive with UDP in case of packet loss. In case of packet loss you can still extrapolate the movements. With each packet send a packet number so that the server knows when the command was sent.
I highly recommend that you download the Quake source code where you can learn more about network programming in modern multiplayer games. It's really easy to read and understand.
edit:
I almost forgot..
Google's Protocol Buffers can be of great help when sending complex data structures.
I thought I would give my two cents and provide a practical application to what is being referred to as Binary Serialization. The concept is actually incredibly simple, yet only seems complicated on the outside.
You can actually send XMLs and have a server that processes the data within the XML to different functions within the server itself. You can also just send the server a single number that is stored within the server as a variable. After that, it can process the rest of the data and choose the correct course of actions.
As an example, some rough code:
private const MOVE_RIGHT:int = 0;
private const MOVE_LEFT:int = 1;
private const MOVE_UP:int = 2;
private const MOVE_DOWN:int = 3;
function processData(e:event.data)
{
switch (e)
{
case MOVE_RIGHT:
//move the clients player to the right
case MOVE_LEFT:
//move the clients player to the left
case MOVE_UP:
//move the clients player to the up
case MOVE_DOWN:
//move the clients player to the down
}
}
This would be a very simple example, and would need to be modified but as you can see you merely just store the variables encoded with whole numbers that you transmit in strings of numbers. You can parse these and create headers of information to organize them into different sections of data that needs to be transmitted.
Also, it is better to do a UDP setup for games because just missing a packet should NOT halter the gaming experience, but instead should be able to handle it client-side AND server-side.

Resources