Question

I have just started using the Poco library. I am having issues getting two computers to communicate using Poco's DatagramSocket objects. Specifically, the receiveBytes function does not seem to return (despite running Wireshark and seeing that the UDP packets I am sending ARE arriving at the destination machine). I assume I am omitting something simple and this is all due to a dumb mistake on my part. I have compiled Poco 1.4.3p1 on Windows 7 using Visual Studio Express 2010. Below are code snippets showing how I am trying to use Poco. Any advise would be appreciated.

Sending

#include "Poco\Net\DatagramSocket.h"
#include "Serializer.h" //A library used for serializing data

int main()
{
   Poco::Net::SocketAddress remoteAddr("192.168.1.140", 5678); //The IP address of the remote (receiving) machine
   Poco::Net::DatagramSocket mSock; //We make our socket (its not connected currently)
   mSock.connect(remoteAddr); //Sends/Receives are restricted to the inputted IPAddress and port
   unsigned char float_bytes[4];
   FloatToBin(1234.5678, float_bytes); //Serializing the float and storing it in float_bytes
   mSock.sendBytes((void*)float_bytes, 4); //Bytes AWAY!
   return 0;
}

Receiving (where I am having issues)

#include "Poco\Net\DatagramSocket.h"
#include "Poco\Net\SocketAddress.h"
#include "Serializer.h"
#include <iostream>

int main()
{
   Poco::Net::SocketAddress remoteAddr("192.168.1.116", 5678); //The IP address of the remote (sending) machine
   Poco::Net::DatagramSocket mSock; //We make our socket (its not connected currently)
   mSock.connect(remoteAddr); //Sends/Receives are restricted to the inputted IPAddress and port
   //Now lets try to get some datas
   std::cout << "Waiting for float" << std::endl;
   unsigned char float_bytes[4];
   mSock.receiveBytes((void*)float_bytes, 4); //The code is stuck here waiting for a packet. It never returns...
   //Finally, lets convert it to a float and print to the screen
   float net_float;
   BinToFloat(float_bytes, &net_float); //Converting the binary data to a float and storing it in net_float
   std::cout << net_float << std::endl;
   system("PAUSE");
   return 0;
}

Thank you for your time.

Was it helpful?

Solution

The POCO sockets are modeled on the Berkeley sockets. You should read a basic tutorial on the Berkeley socket API, this will make it easier to understand the POCO OOP socket abstractions.

You cannot connect() on both client and server. You connect() on the client only. With UDP, connect() is optional, and can be skipped (then you have to use sendTo() instead of SendBytes()).

On the server, either you bind() on the wildcard IP address (meaning: will then receive on all the available network interfaces on the host), or to a specific IP address (meaning: will then receive only on that IP address).

Looking at your receiver/server code, it seems you want to filter on the address of the remote client. You cannot do it with connect(), you have to read with receiveFrom(buffer, length, address) and then filter yourself on "address".

Security-wise, be careful with the assumptions you make with the source address of the UDP packets you receive. Spoofing a UDP packet is trivial. Said in another way: do not make authentication or authorization decisions based on an IP address (or on anything not secured by proper cryptography).

The POCO presentation http://pocoproject.org/slides/200-Network.pdf explains, with code snippets, how to do network programming with POCO. See slides 15, 16 for DatagramSocket. Note that on slide 15 there is a typo, replace msg.data(), msg.size() with syslogMsg.data(), syslogMsg.size() to compile :-)

Have a look also at the "poco/net/samples" directory for short examples that show also the best practices in using POCO.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top