Android to Windows tcp-communication delay - c++

I have developed an android client application and a windows c++ server application which communicate with tcp/ip in a local network.
The data exchange works well on my laptop (win 8, connected to the network with wifi).
On my second pc (win 7) the incoming messages are collected and forwarded in a bunch of about 20 messages to my application. As a consequence I only get about two times per second updates of the current sensor data (on the laptop ~30 times per second).
Both computers and the android phone are in the same local network. There are no other devices in the network and it is not connected to the internet. I already tried a wifi connection and a lan connection for the second pc without noticeable differences.
I assume that any windows 7 setting is responsible for this behavior.

You are using nagling which batches small sends for 200ms. Disable it, but make sure to send big chunks at a time. Each send call immediately goes on the network now.

Related

Computers on LAN do not consistently receive a UDP broadcast to 255.255.255.255 using boost::asio C++

I am quite new to network programming, but nonetheless I am working on a personal project that requires interfacing between two computers on the LAN.
For all of my networking needs, I am using boost.
Since computers running my software on the LAN do not know one another's IP addresses, the program immediately sends a UDP broadcast to 255.255.255.255. Another computer listens on the port 25566. If a computer receives a broadcast, it replies with another broadcast to ensure that the other connects via a TCP connection in the appropriate manner.
I have a laptop, and a desktop, both running Linux. If I test the code (two instances of the same thing) on the same machine, everything works flawlessly. However, a problem arises when I run one instance on the laptop, and another on the desktop. Two scenarios happen:
The first - I run one instance of the program on the Desktop computer. It sends a "Hello" message to check if another instance is running anywhere else on the LAN. Since there is no other instance running, it receives no response. Several seconds later, after the desktop instance sets itself up, I start an instance of the program on the laptop. The laptop broadcasts a "Hello" message as well. However, this is where the problem kicks in. When the laptop is the one sending the "Hello" message, there is only about a 10% chance that the desktop program (already running) actually receives it. I monitored the network with Wireshark on the desktop machine, and, again, Wireshark only picks up the broadcast from the laptop 10% of the time. However, if I run Wireshark on the laptop that is sending the "Hello" broadcast, Wireshark picks it up every single time.
The second - This is similar to the first, except the laptop runs the program first. I then start the desktop instance several seconds later. However, when the desktop broadcasts "Hello" the laptop receives the broadcast about 95% of the time (in contrast to 10% of the time when the roles are reversed). The laptop then responds with a "Configure" broadcast. The desktop then receives the "Configure" broadcast nearly 100% of the time. I confirmed the 95% receive rate with Wireshark again.
I am certain there is no problem with my program ignoring these packets. However, something is happening in the network where the broadcast packets are ignored or filtered. What I find particularly strange is how the desktop program only receives the "Hello" message 10% of the time in scenario 1, but receives the "Configure" message 100% of the time in scenario 2. If something strange was happening that prevented packets from reaching the desktop, woulden't both of those percentages be roughly equal?
Here is some of the code that I run to setup the necessary sockets:
broadcast_socket = new udp::socket(*ioservice); //Set up the socket that broadcasts the message
listen_socket = new udp::socket(*ioservice); //Set up the socket on port 25565 that listens for a broadcast
//Set up the ioservice...
error_code e1, e2;
broadcast_socket->open(udp::v4(), e1); //Actually open the sockets
listen_socket->open(udp::v4(), e2);
//Do some error code checking...
listen_endpoint = udp::endpoint(ip::address_v4::any(), port); //Get endpoint for port 25566 (listen_endpoint becomes 0.0.0.0:25566 after this call)
listen_socket->set_option(udp::socket::reuse_address(true));
listen_socket->bind(listen_endpoint);
broadcast_socket->set_option(udp::socket::reuse_address(true));
broadcast_socket->set_option(socket_base::broadcast(true));
broadcast_endpoint = udp::endpoint(ip::address_v4::broadcast(), port); //Get the broadcast_endpoint (returns 255.255.255.255)
Here is the code I use to receive broadcasted messages:
error_code ec;
size_t available_bytes = listen_socket->available(ec); //See if data is available
size_t read_bytes = 0;
char buffer[1024];
if(available_bytes > 0 && !ec){
read_bytes = listen_socket->receive_from(boost::asio::buffer(buffer, (available_bytes < sizeof(buffer) ? available_bytes : sizeof(buffer))), listen_endpoint);
read_data.append(buffer, read_bytes); //Append to a string for later processing
}
And finally, here is how I send data:
std::string payload = "Some payload stuff goes here";
broadcast_socket->send_to(boost::asio::buffer(payload, payload.size()), broadcast_endpoint); //Broadcasts to the broadcast_endpoint (255.255.255.255) which was determined earlier
So essentially my question is, why does some of my broadcasts not get through?
Thanks
EDIT:
Also, I forgot to mention that each computer receives its OWN broadcast every single time. So I think its a problem with the network, and not my code.
UDP is not guaranteed to deliver. That's part of the properties of the protocol.
The fact that you can observe the behaviour with Wireshark confirms that it has little to do with Boost.
Using 255.255.255.255 is a blunt weapon and it is limited:
Setting all the bits of an IP address to one, or 255.255.255.255, forms the limited broadcast address. Sending a UDP datagram to this address delivers the message to any host on the local network segment. Because routers never forward messages sent to this address, only hosts on the network segment receive the broadcast message.
You can be more targeted by using the subnet mask:
Broadcasts can be directed to specific portions of a network by setting all bits of the host identifier. For example, to send a broadcast to all hosts on the network identified by IP addresses starting with 192.168.1, use the address 192.168.1.255.
This heightens the chance that the router will know where to send the packet (I'm not a network engineer, so I'm not sure about the implementation details).
Enter Multicast Groups:
Unlike broadcast transmission (which is used on some local area networks), multicast clients receive a stream of packets only if they have previously elect to do so (by joining the specific multicast group address). Membership of a group is dynamic and controlled by the receivers (in turn informed by the local client applications).
(source: http://www.erg.abdn.ac.uk/users/gorry/course/intro-pages/uni-b-mcast.html)
This is more likely to fit your application. You'll have to select a good group endpoint depending on the network configuration, so it's slightly more involved.
Yet, you'll have support of all modern router hardware/software to ensure delivery to the interested parties (only).

TCP streams on iOS don't show up on a wireless network

I am trying to send and receive TCP streams from an iPad via a wireless connection to a laptop. I create sockets with boost::asio. This project is a port of a data streaming library that I maintain that works quite well on Windows, OSX, and Linux.
I can get the app to send and receive streams to/from other computers on a wired LAN when I run it on the simulator. But, when I target the device itself, I can't see any streams.
As I say, I am communicating via wireless between an iPad and a laptop. I create a wireless network on the laptop and then give the iPad a static IP. The connection appears to be fine, because I can ping the iPad with no packet loss. I have also tried connecting the devices by putting them on the same wireless LAN (although I'm not supposed to use wireless routers at work) and this also does not work.
According to apple, setting up streams like this with NSStream will just work. Maybe there is some permissions magic happening under the hood that I am not doing with my calls to boost::asio functions. In any case, I can't see the streams.
Actually, it turns out the only thing that was wrong was that I needed to set up my routing table so that it pointed multicast to the wireless card:
> sudo route -nv add -net 224.0.0.183 -interface en1
I got the IP from inspecting packets in wireshark -- it is the address that my device is multicasting to in my laptop. Sending works (from device to laptop), receiving is still silent though. This may be something else that needs to be set int the routing table (I really don't understand much at all about multicasting) or else I can fiddle with some config settings with my library.

Can I connect to more than one Bluetooth HCI at the same time?

I have a project where I don't have enough throughput with one Bluetooth CSR USB dongle to support 3-4 heart monitors at the same time. Is there a way to connect to more than one bluetooth HCI so I can connect to more heart monitors?
If you run two instances of your bluetooth stack / driver then yes you can, But you will have to manage these 2 applications separately.
I have never seen any standard / commercial stack that handles two HCIs simultaneously.

Can a VeriFone terminal application communicate via Ethernet, but also store local data?

Ideally, I would connect a VeriFone terminal to the Internet via an Ethernet cable and transmit transaction data in real time, but I also want to program the terminal to be able to work in offline mode and save transaction data to a file to transmit later. Is this possible?
I would also like to know how much of the communication is with the processing host vs the merchant services provider's application.
Yes, you can but you will need a SDK for that and what goes on or offline depends on your needs. On a Vx510 device you have access to file system, LAN, dial-up or gprs communication, keyboard, printer, display and a lot more.

C/C++ Windows traffic blocker

I want to develop a bandwidth allocator to a network which will be behind my machine.
Now, I've read about NDIS but I am not sure whether the network traffic that is neither originating from my machine nor is destined for my machine will enter my TCP/IP stack, so that I can block/unblock packets via NDIS on a windows machine.
NDIS (kernel) drivers live in the Windows network stack, and so can only intercept packets which are handled by this stack.
You cannot filter packets which are not send to your computer.
(When the computer acts as a router, the packets are send to the computer and the computer forwards the packets to the actual recepient, if that was the question)
In normal operation mode the irrelevant traffic will be dropped by the NIC driver/firmware, like pointed above. However, this is a SW issue so this behavior can be changed by adding an appropriate logic into the device driver and/or firmware. This is how sniffers operate, for example.