Using WinPcap I crafted a series of custom UDP packets and injected them into the Ethernet layer.
I sent 1000 packets, 1440 bytes each. It takes 2.1 sec for 100 Mbps bandwidth.
How do I make use of full bandwidth?
Your throughput seems to be exactly the max you'd get for a 10 mbit connection. Sure there's no 10mbit involved anywhere ?
Originally I misread the question, and thought that it was a duplicate of this. But the 100Mbps makes it completely different.
Even very modest hardware should be able to saturate a 100Mbps connection with no problems - particularly if you're using 1440 byte udp packets.
As suggested by krosenvold, the figures do look suspiciously like a 10Mbps connection, rather than 100Mbps. I would check all of the links from end to end to make sure that they are at the 100Mbps that you believe them to be. Any 10Mbps link in that chain is going to be a problem.
Depending on the equipment that you're using you may find that there have been issues with link autonegotiation. Some equipment is notoriously bad, so you may find better results by turning autonegotiation off, and forcing the link speeds to 100Mbps.
And as you have a pcap file that you're using, I would suggest trying tcpreplay to do some speed testing. There are several options that tcpreplay provides to replay files at the highest possible speed. (in particular, look at this wiki entry)
If that gives you different results than you're seeing at the moment it could point to a problem with the pcap file. For example, the pcap files do contain timing information that can be used when replaying the file. If the timing in your pcap file was taken from a 10Mbps network (for example) then replaying it in real time will give you the result that you're seeing.
Make sure all devices and mediums on the data exchange route are operating at 100 mbps, a connection is only as fast as it's weakest link. Also make sure all devices (including your network card) are operating in Full-Duplex mode.
What about CPU usage during the transfer?
We need to find the bottleneck. It can be the NIC/network or the CPU.
Make sure that you are not "opening" the NIC for each packet.
Wrong:
loop{
OpenDevice
SendPacket
}
Good:
OpenDevice
loop{
SendPacket
}
Related
I want multiple IoT devices (Say 50) communicating to a server directly asynchronously via TCP. Assume all of them have a heartbeat pulse every 30 seconds and may drop off and reconnect at variable times.
Can anyone advice me the best way to make sure no data is dropped or blocked when multiple devices are communicating simultaneously?
TCP by itself ensures no data loss during the communication between a client and a server. It does that by the use of sequence numbers and ACK messages.
Technically, before the actual data transfer happens, a TCP connection is created between the client (which can be an IoT device, or any other device) and the server. Then, the data is split into multiple packets and sent over the network through that connection. All TCP-related mechanisms like flow-control, error-detection, congestion-detection, and many others, take place once the data starts to flow.
The wiki page for TCP is a pretty good start if you want to learn more about how it works.
Apart from that, as long as your server has enough capacity to support the flow of requests coming from the devices, then everything should work (at least in theory).
I don't think you are asking the right question. There is no way to make sure that no data is dropped or blocked. Networks do not always work (that is why the word work is in network, to convince you otherwise ).
The right question is: how do I make my distributed system as available and reliable as possible? The answer involves viewing interruption and congestion as part of the normal operation, and build your software appropriately.
There is a timeless usenix/acm/? paper from the late 70s early 80s that invigorated the notion that end-to-end protocols are much more effective then over-featured middle to middle protocols; and most guarantees of middle to middle amount to best effort. If you rely upon those guarantees, you are bound to fail. Sorry, cannot find the reference right now, but it is widely cited.
Since packets travel over the wire have checksums on different layers, Ethernet and IPv4 have checksums for their headers, TCP's checksum even covers the entire segment.
I know it is not impossible that a corrupted packet, from the standpoint of the application layer, can slip in without being discarded by Ethernet/IP/TCP, because there are chances that their checksums are correct, only the probability is low.
I am designing a custom binary protocol for an IM application. My question is do I need to add a checksum to ensure the integrity of my application data? Is a checksum really needed in practice?
There's actual research on this subject. It's old, but very relevant to the question at hand.
The paper, from 2000, is called "When the CRC and TCP checksum disagree" by Jonathan Stone and Craig Partridge, which investigate packet and frame errors, and look how often the TCP checksum is wrong, but the Ethernet CRC is fine. You can find the PDF here. Here are the important bits.
From the abstract:
Traces of Internet packets from the past two years show that between 1
packet in 1,100 and 1 packet in 32,000 fails the TCP checksum, even on
links where link-level CRCs should catch all but 1 in 4 billion
errors.
From the conclusion (with some of my highlighting)
In practice, the checksum is being asked to detect an error every
few thousand packets. After eliminating those errors that the checksum
always catches, the data suggests that, on average, between one packet
in 10 billion and one packet in a few millions will have an error that
goes undetected. The exact range depends on the type of data
transferred and the path being traversed. While these odds seem large,
they do not encourage complacency. In every trace, one or two 'bad
apple' hosts or paths are responsible for a huge proportion of the
errors. For applications which stumble across one of the `bad-apple'
hosts, the expected time until a corrupted data is accepted could be
as low as a few minutes. When compared to undetected error rates for
local I/O (e.g., disk drives), these rates are disturbing. Our
conclusion is that vital applications should strongly consider
augmenting the TCP checksum with an application sum.
I don't know of any newer research into that question (enlighten me if you know otherwise!), so the Internet could have become more reliable since then, and the numbers in the paper might be irrelevant.
However, and this is important, 17 years have passed, and the amount of Internet traffic simply exploded since that paper was written. At 1Gbps, which is not an uncommon connection speed nowadays, you're sending about 81K full TCP segments, with 1460 bytes of data, per second (or a lot more if the packets are smaller). That's a million big packets every 12.5 seconds, a billion in about 3.5 hours (or again, a lot more if the packets are small).
So to answer your question - that depends.
For transferring large files or other data, I'd definitely add additional checks if the data itself isn't protected in any way. For messaging, which pushes very little data into the network, you'll probably be fine with TCP's checksum, with maybe some sanity checks on the input you're getting to make sure that it's in the correct format, and various parameters and fields make sense.
I would not bother with a checksum because of packets getting corrupted in the network.
However, since you are working on a protocol that would presumably be used on the open internet, you will need to prepare for rare cases of an unintended application sending udp packets or making tcp connections to your receiving/listening ports. Also there will be maybe less port scans and hackers / script kiddies knocking on your gates.
So you should make your protocol such that it is easy to discard this kind of traffic. Using a checksum in every transmission would imho be one sensible way of doing that.
I am working on a project which requires sensor information to be obtained from multiple embedded devices so that it may be used by a master machine. The master currently has classes which contain backing fields for each sensor. Data is continuously read on each sensor and a packet is then written and sent to the master to update that sensor's backing field. I have little experience with TCP/UDP so I am not sure which protocol would work better with this setup.
I am currently using TCP to transfer the data because I am worried about data on our rotary encoders being received out of order. Since my experience with this topic is limited, I am not sure if this is this a valid concern.
Does anyone with experience in this area know any reasons that I should prefer one approach over the other?
How much you care about getting know a packet was delivered?
How much you care about getting know a delivered packet was 100% correct?
How much you care about the order of packet delivery?
How much you care about the peer is currently connected?
If the answers were "I care a lot", you'd prefer to keep on using TCP because it ensure all four points.
The counterpart is that UDP could be more lightweight and fast to handle if you manage small packets.
Anyway, it's not so easy choose this or that. Just try.
And read this brief explanation: http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/
I'm no expert but it seems this might be relevant:
Do you can about losing data?
If so, use TCP. Error recovery is automatic.
If not, use UDP. Lost packets are not re-sent. I also believe ordering here is not guaranteed.
We are making an application involving a server(tomcat, apache, linux) and multiple mobile clients(Android, iPhone, Windows, Nokia J2ME).
Normally the clients and the server will communicate using http.
I would like to know the download and upload speeds of the client from the http request that it made.
Ideally I would not like to upload a file and download a file to come up with these speeds. I am assuming that there might be some thing at the HTTP protocol level that can give me this, or some lower layer of the network.
If only it were that simple.
Even where the bandwidth and latency of a network are very well defined, the actual throughput will be limited by the congestion window and where the end points are in establishing the slow start threshold. These can affect throughput by a factor of 20 or more.
There's nothing in HTTP which will provide metrics for these. Some TCP stacks will expose limited information about throughput (as used by iftop, iptraf).
However if you really want to gather useful metrics on HTTP throughput, then you need to start shoving data across the network - have a look at yahoo boomerang for an implementation.
If the http connection goes to the Apache server first, you can use Apache Bench to do all sorts of load testing. It comes with apache and can be invoked with something like the following.
Suppose we want to see how fast Yahoo can handle 100 requests, with a maximum of 10 requests running concurrently:
ab -n 100 -c 10 http://www.yahoo.com/
HTTP does not deal with connection speeds. Although I could imagine some solution that involves some HTTP (reverse) proxy that estimates speeds on a connection and sets custom headers to pass this info. You would also need to to associate stats of different connections with particular client. I have not seen yet a readily available solution for this.
Also note that
network traffic can be buffered or shaped so download speed may depend on amount of data transferred or previous load of network. So even downloading file would not be accurate.
Amount of data transferred depends on protocol level (payload wrapped in HTTP wrapped in gzip wrapped in TLS wrapped TCP). Which one do you want to measure? Or what do you want to achieve with this measured speed?
I've seen some Real User Monitoring (RUM) tools that can do this passively (they get a feed from a SPAN port or network TAP infront of the servers at the data centre)
There are probably ways of integrating the data they produce into your applications but I'm not sure it would be easy or perhaps given the way latency and bandwidth can 'dynamically' change on a mobile network that accurate.
I guess the real thing to focus on is the design of the app, how much data is travelling across the network, how you can minimise it etc.
Other thing to consider is whether you could offer a solution that allows some of the application to be hosted in the telco's POPs (some telcos route all their towers back to a central pop, others have multiple POPs)
I need (to design?) a protocol for communication between a microprocessor-driven data logger, and a PC (or similar) via serial connection. There will be no control lines, the only way the device/PC can know if they're connected is by the data they're receiving. Connection might be broken and re-established at any time. The serial connection is full-duplex. (8n1)
The problem is what sort of packets to use, handshaking codes, or similar. The microprocessor is extremely limited in capability, so the protocol needs to be as simple as possible. But the data logger will have a number of features such as scheduling logging, downloading logs, setting sample rates, and so on, which may be active simultaneously.
My bloated version would go like this: For both the data logger and PC, a fixed packet size of 16 bytes with a simple 1 byte check sum, perhaps a 0x00 byte at the beginning/end to simplify recognition of packets, and one byte denoting the kind of data in the packet (command / settings / log data / live feed values etc). To synchronize, a unique "hello/reset" packet (of all zero's for example) could be sent by the PC, which when detected by the device is then returned to confirm synchronization.
I'd appreciate any comments on this approach, and welcome any other suggestions as well as general observations.
Observations: I think I will have to roll my own, since I need it to be as lightweight as possible. I'll be taking bits and pieces from protocols suggested in answers, as well as some others I've found... Slip,
PPP and HLDC.
You can use Google's Protocol Buffers as a data exchange format (also check out the C bindings project if you're using C). It's a very efficient format, well suited to such tasks.
Microcontroller Interconnect Network (MIN) is designed for just this purpose: tiny 8-bit microcontrollers talking to something else.
The code is MIT licensed and there's embedded C and also Python implementations:
https://github.com/min-protocol/min
I wouldn't try to invent something from scratch, perhaps you could reuse something from the past like ZMODEM or one of its cousins? Most of the problems you mention have been solved, and there are probably a number of other cases you haven't even though of yet.
Details on zmodem:
http://www.techfest.com/hardware/modem/zmodem.htm
And the c source code is in the public domain.