I need a solution to transmit one audio channel (mono) 44.1 Khz, 16 bit resp. 88.2 KB/Sec with less than 100 ms latency to a remote location. The application is for a remote concert. My software is built on Windows 10 with Max (cycling74), Java, Unity and C#. I want send data as well between the applications especially from Max to Java and Unity. I found zeromq and apache kafka as possible frameworks. I would appreciate to get some hints which tools could be suited. As I am not very experienced in network programming minimizing the effort for an implementation is also an important concern.
ZeroMQ is capable of sub millisecond latency on an internal network. However, I would recommend raw UDP sockets. UDP doesn't retransmit lost packets and has very low overhead compared to TCP (used by ZMQ).
You may also need to do traffic prioritization on your network to ensure a reasonable latency, but with the small quantity of data you are using it might not have a significant effect (this all depends on your specific network). I would start with implementing a UDP socket then if you are seeing unacceptable latencies try to optimize the network.
Is it possible to calculate bandwidth of networking applications (TCP/UDP) by using Win32 API on Windows?
AFAIK TCP bandwidth calculation can be done by using GetPerTcpConnectionEStats
function. But I could not find any function for UDP.
PSPing seems to be working for UDP, therefore I assume that there must be a way to measure the bandwidth of UDP connections somewhere. Am I right?
Is there any other coding method to gather instant UDP bandwidth usage per connection on Windows?
I am trying to run a simulation to test packet loss in an environment where packet collision is happening. My current setup includes several discrete machines each with their own network interface to send/receive packets. These machines are connected by wifi through an AP. I'm currently using UDP for its ability to broadcast packets on a single address. All machines are listening on a shared IP address, something like 192.168.1.255.
This answer mentions that UDP packets are unreliable, but will they fail because of a collision? Here, I use collision to refer to interference caused by multiple simultaneous transmission. That is, will the simultaneous broadcast of two UDP nodes in the network induce the unreliability I am looking to test? If it's not, will I have to look into changing my network configuration or even start tinkering with kernel code?
If the question is vague, I will say that my end goal involves writing some distributed algorithm that may or may not be resistant to collisions.
I am trying to run a simulation to test packet loss in an environment
where packet collision is happening.
You might want to include in your question what you mean by the word collision. I'm going to assume in my answer that you mean it in the traditional sense (i.e. two network endpoints transmitting at approximately the same time and thereby "talking over each other" and garbling each other's transmissions such that neither transmission is successful), and not in any broader sense of "a packet got dropped due to network congestion".
This answer mentions that UDP packets are unreliable, but will they
fail because of a collision?
The answer is going to depend entirely on what sort of network hardware you are running your UDP packets over. The UDP protocol itself is hardware-independent, so it's not going to specify anything about whether collisions can occur or not, since there's no way for it to know.
That said, most low-level networking hardware these days has provisions for avoiding collisions (in the sense I mentioned above) -- for example, modern Ethernet switches do a limited amount of active queueing/buffering of packets when necessary (which is much more efficient and reliable than the old 10Mb/sec Ethernet hubs, which basically just electrically connected the Ethernet RX and TX leads of all the endpoints into one big "shared wire", and hoped for the best)
The other commonly used networking-hardware type, Wi-Fi, also has mechanisms to reduce collisions, but that doesn't mean that UDP broadcast over Wi-Fi is a good idea, because it suffers from other issues -- for one thing, the Wi-Fi router has to receive your broadcast packet and rebroadcast it to make sure all other clients can receive it, and worse, it will typically be set to retransmit it at a very slow "legacy" rate, in order to make sure that any ancient Wi-Fi cards out there can still receive the broadcast data. My advice is that if you're going to be using Wi-Fi, keep your broadcast (and multicast) transmissions to an absolute minimum; even sending separate/identical unicast packets to every other client is usually more efficient(!) -- not to avoid collisions, but rather because even a modest amount of broadcast/multicast traffic can bring your Wi-Fi network to a crawl.
UDP is said to be unreliable because it does not guarantee packet delivery, retransmission, flow control, or congestion. So, the sending/receiving of UDP packets can fail for many reasons: collision, unreliable physical medium, interference, dropping of packets due to router queue overflow, etc.
My goal is to drop as few UDP datagrams as possible. Shocker, I know, ;-)
Here is my circumstance which is a bit different from the general network server/client optimization questions for which I see a lot of discussion:
I am writing socket code for a process which has one singular goal: grab UDP packets received by my Gigabit Ethernet NIC and get them into application RAM with as high a bandwidth as possible (i.e. minimize packet drops/loss).
The network is point-to-point without any firewalls, switches, routers, etc - just a single Cat6 cable connecting the UDP datagram generator/server (an embedded system) with my Windows 7 PC, the datagram receiver/client. I can control the transmitted datagrams-per-second via some controls on the datagram generator. The datagrams are sent to the broadcast address (FF.FF.FF.FF).
I've successfully achieved about 250-300Mbits/sec (30% of the theoretical 1G Ethernet bandwidth) without any packets getting dropped or order-scrambled by using lean-and-mean code based on the built-in Winsock2 commands: select() and recvfrom() as outlined in the sample code for those commands on MSDN.
(I've already adjusted the receive buffer to be very large using the setsockopt() command, and this helped considerably.) But I am still wanting to maximize performance and eager to hear thoughts from this community on whether or not I should expect noticeable gains from trying the following:
Asynchronous I/O, such as boost::asio. From what I gather, this library appears to be more for optimizing applications which have to serve a lot of different sockets to different machines. Should I expect much in terms of single-socket UDP receive performance from switching from Winsock to an asynchronous I/O architecture?
Packet size: If I make the effort to change the packet size by modifying the embedded code that is generating the packets, would it be likely to improve performance by having lots of smaller packets or fewer large/jumbo packets?
Broadcast/multicast/unicast: is one destination address type likely to perform better than others?
Or is 300Mbps about the limit that I should be expecting for actual throughput on a 1G physical link?
Any other recommendations on low-hanging fruit to improve performance, or expectations on what type of performance is feasible.
Thanks all!
Recently, I started using the System.Net.Sockets class introduced in the Mango release of WP7 and have generally been enjoying it, but have noticed a disparity in the latency of transmitting data in debug mode vs. running normally on the phone.
I am writing a "remote control" app which transmits a single byte to a local server on my LAN via Wifi as the user taps a button in the app. Ergo, the perceived responsiveness/timeliness of the app is highly important for a good user experience.
With the phone connected to my PC via USB cable and running the app in debug mode, the TCP connection seems to transmit packets as quickly as the user taps buttons.
With the phone disconnected from the PC, the user can tap up to 7 buttons (and thus case 7 "send" commands with 1 byte payloads before all 7 bytes are sent.) If the user taps a button and waits a little between taps, there seems to be a latency of 1 second.
I've tried setting Socket.NoDelay to both True and False, and it seems to make no difference.
To see what was going on, I used a packet sniffer to see what the traffic looked like.
When the phone was connected via USB to the PC (which was using a Wifi connection), each individual byte was in its own packet being spaced ~200ms apart.
When the phone was operating on its own Wifi connection (disconnected from USB), the bytes still had their own packets, but they were all grouped together in bursts of 4 or 5 packets and each group was ~1000ms apart from the next.
btw, Ping times on my Wifi network to the server are a low 2ms as measured from my laptop.
I realize that buffering "sends" together probably allows the phone to save energy, but is there any way to disable this "delay"? The responsiveness of the app is more important than saving power.
This is an interesting question indeed! I'm going to throw my 2 cents in but please be advised, I'm not an expert on System.Net.Sockets on WP7.
Firstly, performance testing while in the debugger should be ignored. The reason for this is that the additional overhead of logging the stack trace always slows applications down, no matter the OS/language/IDE. Applications should be profiled for performance in release mode and disconnected from the debugger. In your case its actually slower disconnected! Ok so lets try to optimise that.
If you suspect that packets are being buffered (and this is a reasonable assumption), have you tried sending a larger packet? Try linearly increasing the packet size and measuring latency. Could you write a simple micro-profiler in code on the device ie: using DateTime.Now or Stopwatch class to log the latency vs. packet size. Plotting that graph might give you some good insight as to whether your theory is correct. If you find that 10 byte (or even 100byte) packets get sent instantly, then I'd suggest simply pushing more data per transmission. It's a lame hack I know, but if it aint broke ...
Finally you say you are using TCP. Can you try UDP instead? TCP is not designed for real-time communications, but rather accurate communications. UDP by contrast is not error checked, you can't guarantee delivery but you can expect faster (more lightweight, lower latency) performance from it. Networks such as Skype and online gaming are built on UDP not TCP. If you really need acknowledgement of receipt you could always build your own micro-protocol over UDP, using your own Cyclic Redundancy Check for error checking and Request/Response (acknowledgement) protocol.
Such protocols do exist, take a look at Reliable UDP discussed in this previous question. There is a Java based implementation of RUDP about but I'm sure some parts could be ported to C#. Of course the first step is to test if UDP actually helps!
Found this previous question which discusses the issue. Perhaps a Wp7 issue?
Poor UDP performance with Windows Phone 7.1 (Mango)
Still would be interested to see if increasing packet size or switching to UDP works
ok so neither suggestion worked. I found this description of the Nagle algorithm which groups packets as you describe. Setting NoDelay is supposed to help but as you say, doesn't.
http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.nodelay.aspx
Also. See this previous question where Keepalive and NoDelay were set on/off to manually flush the queue. His evidence is anecdotal but worth a try. Can you give it a go and edit your question to post more up to date results?
Socket "Flush" by temporarily enabling NoDelay
Andrew Burnett-Thompson here already mentioned it, but he also wrote that it didn't work for you. I do not understand and I do not see WHY. So, let me explain that issue:
Nagle's algorithm was introduced to avoid a scenario where many small packets had to been sent through a TCP network. Any current state-of-the-art TCP stack enables Nagle's algorithm by default!
Because: TCP itself adds a substantial amount of overhead to any the data transfer stuff that is passing through an IP connection. And applications usually do not care much about sending their data in an optimized fashion over those TCP connections. So, after all that Nagle algorithm that is working inside of the TCP stack of the OS does a very, very good job.
A better explanation of Nagle's algorithm and its background can be found on Wikipedia.
So, your first try: disable Nagle's algorithm on your TCP connection, by setting option TCP_NODELAY on the socket. Did that already resolve your issue? Do you see any difference at all?
If not so, then give me a sign, and we will dig further into the details.
But please, look twice for those differences: check the details. Maybe after all you will get an understanding of how things in your OS's TCP/IP-Stack actually work.
Most likely it is not a software issue. If the phone is using WiFi, the delay could be upwards of 70ms (depending on where the server is, how much bandwidth it has, how busy it is, interference to the AP, and distance from the AP), but most of the delay is just the WiFi. Using GMS, CDMA, LTE or whatever technology the phone is using for cellular data is even slower. I wouldn't imagine you'd get much lower than 110ms on a cellular device unless you stood underneath a cell tower.
Sounds like your reads/writes are buffered. You may try setting the NoDelay property on the Socket to true, you may consider trimming the Send and Receive buffer sizes as well. The reduced responsiveness may be a by-product of there not being enough wifi traffic, i'm not sure if adjusting MTU is an option, but reducing MTU may improve response times.
All of these are only options for a low-bandwidth solution, if you intend to shovel megabytes of data in either direction you will want larger buffers over wifi, large enough to compensate for transmit latency, typically in the range of 32K-256K.
var socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
NoDelay = true,
SendBufferSize = 3,
ReceiveBufferSize = 3,
};
I didn't test this, but you get the idea.
Have you tried setting SendBufferSize = 0? In the 'C', you can disable winsock buffering by setting SO_SNDBUF to 0, and I'm guessing SendBufferSize means the same in C#
Were you using Lumia 610 and mikrotik accesspoint by any chance?
I have experienced this problem, it made Lumia 610 turn off wifi radio as soon as last connection was closed. This added perceivable delay, compared to Lumia 800 for example. All connections were affected - simply switching wifi off made all apps faster. My admin says it was some feature mikrotiks were not supporting at the time combined with WMM settings. Strangely, most other phones were managing just fine, so we blamed cheapness of the 610 at the beginning.
If you still can replicate the problem, I suggest trying following:
open another connection in the background and ping it all the time.
use 3g/gprs instead of wifi (requires exposing your server to the internet)
use different (or upgraded) phone
use different (or upgraded) AP