UDP socket buffer overflow detection - c++

I'm developing cross-platform tool that captures multiple udp streams with various bit-rate.
boost::asio is used for networking. Is there any way to detect the situation when the udp buffer was full and data loss on socket could take place? The only way I can see now is reading /proc/%pid%/net/udp, but it's not aplicable for windows as you know :). Also I'd like to use boost features for it if possible.

If you need this capability, you have to code it into the protocol you are using. UDP is incapable of doing this by itself. For example, you could put a sequence number in each datagram. Missing datagrams would correspond to missing sequence numbers.

I've just hit the same issue (although for me Linux-specific), and despite the question being old might as well document my findings for others.
As far as I know, there are no portable way to do this, and nothing directly supported by Boost.
That said, there are some platform-specific ways of doing it. In Linux, it can be done by setting the SO_RXQ_OVFL socket-option, and then getting the replies using recvmsg(). It's poorly documented though, but you may be helped by http://lists.openwall.net/netdev/2009/10/09/75.
One way to avoid it in the first place is to increase the receive-buffers (I assume you've investigated it already, but including it for completeness). The SO_RCVBUF options seems fairly well-supported cross-platform. http://pubs.opengroup.org/onlinepubs/7908799/xns/setsockopt.html http://msdn.microsoft.com/en-us/library/windows/hardware/ff570832(v=vs.85).aspx OS:es puts an upper limit on this though, which an administrator might have to increase. On Linux, I.E. it can be increased using /proc/sys/net/core/rmem_max.
Finally, one way for your application to assess it's "load", which with large input-buffers might serve for early detection of overloading, could be to introduce a timestamp before and after the async operations. In pseudo_code (not boost::async-adapted):
work_time = 0
idle_time = 0
b = clock.now()
while running:
a = clock.now()
work_time += a-b
data = wait_for_input()
b = clock.now()
idle_time += b-a
process(data)
Then every second or so, you can check and reset work_time / (work_time+idle_time). If it approaches 1, you know you're heading for trouble and can send out an alert or take other actions.

Related

Quickly determine access to ntp server

I'm trying to create a method that determines access to the ntp server. I made a simple method, but if there is no connection, then it waits a long time for an answer - 5 seconds. I check 5 servers like this, for example - time.nist.gov. We have to wait a very long time.
Question: is there an easy way to check to avoid waiting so long, about 1-2 seconds?
bool is_connection(char* url)
{
// time.nist.gov
return gethostbyname(url) != NULL;
}
First, you should do all these checks in separated threads and join them to get the whole results in a single request.
Second, NTP uses UDP, so you can't check if the port (123 for NTP) is open or not, since UDP isn't a connected protocol - i.e. you don't have delivery results unless the server sends back another datagram to acknowledge your datagram. With TCP, you can "ping" a port to check if it's open, but not in UDP. You'll need to dive into RFC 1305 in order to be able to check that.
Resolving the name won't help you to check if it's a valid and working NTP server.
Anyway, your problem can be easily solved, but the solution is most likely dependent of your operating system (type, version, ...), your compiler (type, version, C++ standard used, ...), and the allowed C++ frameworks for your case (open bar, restricted, portable or not, ...).
I highly doubt that an EFFICIENT solution in pure portable C++ exists, in particular if you're stuck with old C++ standards. An efficient solution is more likely totally platform-dependent.
You should precise your working environment in order to get a more precise solution.

How to operate multiple ZeroMQ Socket Types In The Same Process?

I am looking to use ZeroMQ to facilitate IPC in my embedded systems application, however, I'm not able to find many examples on using multiple 0MQ socket types in the same process.
For example, say I have a process called "antenna_mon" that monitors an antenna. I want to be able to send messages to this process and get responses back - a classic REQ-REP pattern. However, I also have a "cm" process, that publishes configuration changes to subscribers. I want antenna_mon to also subscribe to antenna configuration changes - PUB-SUB.
I found this example of reading from multiple sockets in the same process, but it seems sub optimal, because now you no longer block waiting for messages, you inefficiently check for messages constantly and go back to sleep.
Has anyone encountered this problem before? Am I just thinking about it wrong? Maybe I should have two threads - one for CM changes, one for REQ-REP servicing?
I would love any insights or examples of solving this type of problem.
Welcome to the very nature of distributed computing!
Yes, there are new perspectives one has to solve, once assembling a Project for a multi-agent domain, where more than one process works and communicates with it's respective peers ad-hoc.
A knowledge base, acquired from a soft Real-Time System or embedded systems design experience will help a lot here. If none such available, some similarities might be also chosen from GUI design, where a centerpiece is something like a lightweight .mainloop() scheduler, and most of the hard-work is embedded into round-robin polled GUI-devices and internal-state changes or external MMI-events are marshalled into event-triggered handlers.
ZeroMQ infrastructure gives one all the tools needed for such non-blocking, controllably poll-able ( scaleable, variable or adaptively ad-hoc adjustable poll-timeouts, not to overcome the given, design defined, round-trip duration of the controller .mainloop() ) and transport-agnostic, asynchronously operated, message dispatcher ( with thread-mapped performance scaling & priority tuning ).
What else one may need?
Well, just imagination and a lot of self-discipline to adhere the Zero-Copy, Zero-Sharing and Zero-Blocking design maxims.
The rest is in your hands.
Many "academic" examples may seem trivial and simplified, so as to illustrate just the currently discussed, or a feature demonstrated in some narrow perspective.
Not so in the real-life situations.
As an example, my distributed ML-engine uses a tandem of several PUSH/PULL pipelines for moving state data updates transfers and prediction forcasts + another PUSH/PULL for remote keyboard + a reversed .bind()/.connect() on PUB/SUB for easy broadcasting of distributed agents' telemetry to a remote centrally operated syslog and some additional PAIR/PAIR pipes, as processing requires.
( nota bene: one shall always bear in mind, that robust and error-resilient systems ought avoid to use a default REQ/REP Scaleable Formal Communication Pattern, as there is non-zero probability of falling the pairwise-stepped REQ/REP dual-FSA into an unsalvageable deadlock. Do not hesitate to read more about this smart tool. )

Multiple socket 'handshaking' in UDP network using SFML C++ libraries

I am coding a real-time, network program with UDP protocol using SFML libraries. The server will be handling all of the processing, sending packets to the client and vice versa.
I need a method to synchronize the screen updates, because there will be a real-time user interface on both sides of the network. What I am thinking is, I will have the client and server open two ports, 1 for sending the packet and the other as a sort of 'verifying' port.
Once the updates are made and verified, both loops will send a byte over the network indicating that their side is 'ready'. Once a 'ready' side receives that byte, it will know the screen is ready to update on both sides, and then render the updates.
My question is, how would I do this in C++ using SFML libraries. Is the logic correct, will I encounter network errors etc.
Comment if anything needs clearing up.
You should read on the subject to see how it really works, like How do the protocols of real time strategy games such as Starcraft and Age of Empires look?
There is nothing specific to know in terms of SFML as the theory is applicable to every programming languages (that uses sockets). And you've not provided the code that you're struggling with, so I can't help without Minimal, Complete, and Verifiable example.
But one thing I would say is to never wait on the network to render. This will be laggy as hell and if you want "real-time", you must simulate it without real "real-time" as there will always be latency with networking.
And if you go with UDP, you don't have a choice but to open 2 ports, one on the server and one on the client. But I would argue against using a
"confirmation" port as this is useless since you'll be sending multiple times a second anyway.
See how to use sockets with SFML. I guess you already know this but it might be useful for people coming from google.
See SFML networking rts which explains way better than me what to do.
From #muhwu
Generally if you are going for a real-time game with timing critical elements, you should be placing the commands player make slightly to the future to compensate for the latency. This can be few hundred milliseconds at most.
From #sean-middleditch:
Note also that many articles are just really out of date. TCP for instance is a perfectly good choice for networking in a game like an RTS, especially with lock-step networking, and is even the protocol of choice for many smaller MMOs. Despite this, almost every article around on networking is about building a custom UDP protocol.
Speaking of gamedev.stackexchange.com, you might want to read the questions and answers, and if that does not help, then ask one there.
Asking the same question on SO might not be the way to go, as your question is too broad and as already been answered a number of times (like the first one I linked).

Sending large chunks of data over Boost TCP?

I have to send mesh data via TCP from one computer to another... These meshes can be rather large. I'm having a tough time thinking about what the best way to send them over TCP will be as I don't know much about network programming.
Here is my basic class structure that I need to fit into buffers to be sent via TCP:
class PrimitiveCollection
{
std::vector<Primitive*> primitives;
};
class Primitive
{
PRIMTYPES primType; // PRIMTYPES is just an enum with values for fan, strip, etc...
unsigned int numVertices;
std::vector<Vertex*> vertices;
};
class Vertex
{
float X;
float Y;
float Z;
float XNormal;
float ZNormal;
};
I'm using the Boost library and their TCP stuff... it is fairly easy to use. You can just fill a buffer and send it off via TCP.
However, of course this buffer can only be so big and I could have up to 2 megabytes of data to send.
So what would be the best way to get the above class structure into the buffers needed and sent over the network? I would need to deserialize on the recieving end also.
Any guidance in this would be much appreciated.
EDIT: I realize after reading this again that this really is a more general problem that is not specific to Boost... Its more of a problem of chunking the data and sending it. However I'm still interested to see if Boost has anything that can abstract this away somewhat.
Have you tried it with Boost's TCP? I don't see why 2MB would be an issue to transfer. I'm assuming we're talking about a LAN running at 100mbps or 1gbps, a computer with plenty of RAM, and don't have to have > 20ms response times? If your goal is to just get all 2MB from one computer to another, just send it, TCP will handle chunking it up for you.
I have a TCP latency checking tool that I wrote with Boost, that tries to send buffers of various sizes, I routinely check up to 20MB and those seem to get through without problems.
I guess what I'm trying to say is don't spend your time developing a solution unless you know you have a problem :-)
--------- Solution Implementation --------
Now that I've had a few minutes on my hands, I went through and made a quick implementation of what you were talking about: https://github.com/teeks99/data-chunker There are three big parts:
The serializer/deserializer, boost has its own, but its not much better than rolling your own, so I did.
Sender - Connects to the receiver over TCP and sends the data
Receiver - Waits for connections from the sender and unpacks the data it receives.
I've included the .exe(s) in the zip, run Sender.exe/Receiver.exe --help to see the options, or just look at main.
More detailed explanation:
Open two command prompts, and go to DataChunker\Debug in both of them.
Run Receiver.exe in one of the
Run Sender.exe in the other one (possible on a different computer, in which case add --remote-host=IP.ADD.RE.SS after the executable name, if you want to try sending more than once and --num-sends=10 to send ten times).
Looking at the code, you can see what's going on, creating the receiver and sender ends of the TCP socket in the respecitve main() functions. The sender creates a new PrimitiveCollection and fills it in with some example data, then serializes and sends it...the receiver deserializes the data into a new PrimitiveCollection, at which point the primitive collection could be used by someone else, but I just wrote to the console that it was done.
Edit: Moved the example to github.
Without anything fancy, from what I remember in my network class:
Send a message to the receiver asking what size data chunks it can handle
Take a minimum of that and your own sending capabilities, then reply saying:
What size you'll be sending, how many you'll be sending
After you get that, just send each chunk. You'll want to wait for an "Ok" reply, so you know you're not wasting time sending to a client that's not there. This is also a good time for the client to send a "I'm canceling" message instead of "Ok".
Send until all packets have been replied with an "Ok"
The data is transfered.
This works because TCP guarantees in-order delivery. UDP would require packet numbers (for ordering).
Compression is the same, except you're sending compressed data. (Data is data, it all depends on how you interpret it). Just make sure you communicate how the data is compressed :)
As for examples, all I could dig up was this page and this old question. I think what you're doing would work well in tandem with Boost.Serialization.
I would like to add one more point to consider - setting TCP socket buffer size in order to increase socket performance to some extent.
There is an utility Iperf that let test speed of exchange over the TCP socket. I ran on Windows a few tests in a 100 Mbs LAN. With the 8Kb default TCP window size the speed is 89 Mbits/sec and with 64Kb TCP window size the speed is 94 Mbits/sec.
In addition to how to chunk and deliver the data, another issue you should consider is platform differences. If the two computers are the same architecture, and the code running on both sides is the same version of the same compiler, then you should, probably, be able to just dump the raw memory structure across the network and have it work on the other side. If everything isn't the same, though, you can run into problems with endianness, structure padding, field alignment, etc.
In general, it's good to define a network format for the data separately from your in-memory representation. That format can be binary, in which case numeric values should be converted to standard forms (mainly, changing endianness to "network order", which is big-endian), or it can be textual. Many network protocols opt for text because it eliminates a lot of formatting issues and because it makes debugging easier. Personally, I really like JSON. It's not too verbose, there are good libraries available for every programming language, and it's really easy for humans to read and understand.
One of the key issues to consider when defining your network protocol is how the receiver knows when it has received all of the data. There are two basic approaches. First, you can send an explicit size at the beginning of the message, then the receiver knows to keep reading until it's gotten that many bytes. The other is to use some sort of an end-of-message delimiter. The latter has the advantage that you don't have to know in advance how many bytes you're sending, but the disadvantage that you have to figure out how to make sure the the end-of-message delimiter can't appear in the message.
Once you decide how the data should be structured as it's flowing across the network, then you should figure out a way to convert the internal representation to that format, ideally in a "streaming" way, so you can loop through your data structure, converting each piece of it to network format and writing it to the network socket.
On the receiving side, you just reverse the process, decoding the network format to the appropriate in-memory format.
My recommendation for your case is to use JSON. 2 MB is not a lot of data, so the overhead of generating and parsing won't be large, and you can easily represent your data structure directly in JSON. The resulting text will be self-delimiting, human-readable, easy to stream, and easy to parse back into memory on the destination side.

boost asio: 0 byte write

I need some help understanding a peculiar issue I'm having when using asio.
I've a client -server app, with a c++ client(using boost asio) sending 2 byte hearbeat (say, every second) to a server(written in java) (and receiving lots of data as well).
for a quite a few minutes the server correctly receives the 2 byte HeartBeat, but after that the server's 'read' complains abt a 0 byte read, and closes the connection (which I guess is correct for a blocking read). The client however always prints out that it's been transferring the correct amount.
I've experimented with almost all variants of the 'write' family of functions. are all of them implemented in terms of 'write_some' and does that mean that this behavior is expected?
I must be making some mistake in my usage, basically I'm looking for something within asio that guarantees a write ( at least a byte) . please help me figure out where I'm going wrong(and if any further info is reqd.)...
any advice, most appreciated!
thanks!
If it's sockets, you can't "guarantee a write"; what if the network is down, the cable yanked out, the switch is on fire, or the power is out worldwide and your computer happens to be the only one running on batteries?
That said, it sounds as if you have some kind of buffering/emptying issue perhaps, check over your read code to make sure it really consumes all data that appears.
A 0-byte read is not an error, look over that code again, check for any error status flags on the socket(s) and so on. A read can fail with a "AGAIN"-status, which really means you should try again.
strace the applications at both ends. It will show any error codes that are returned by read(), write() etc. Use strace -f if the application is multithreaded.
The advantage of this approach is that all applications - java, c++, python appear the same in an strace, so it's easy to spot bad behaviour.
In this case, it would probably show that the tcp connection ended (gracefully).