Boost UDP client.. How to set up?

Hi guys.
I am at the moment trying to set up a Client which can interact with an server, and read the messages from it.

My intention was to use the boost Library, but the documentation make me more confused than ever..

I am not getting any reasonable feedback when I try to send some data to it.. Making me wonder whether i am doing the right thing..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using namespace std;

#define OPEN_UDP_PORT               0
#define SEND_DATA_TO_SERVER         1
#define RECEIVE_ANSWER_FROM_SERVER  2
#define CLOSE_UDP_PORT              3
#define RECEIVE_DATA               20
#define ERROR                      10

using boost::asio::ip::udp;

class UDPClient
{
public:
	UDPClient(
		boost::asio::io_service& io_service,
		const std::string& host,
		const std::string& port
	) : io_service_(io_service), socket_(io_service, udp::endpoint(udp::v4(), 0)) {
		udp::resolver resolver(io_service_);
		udp::resolver::query query(udp::v4(), host, port);
		udp::resolver::iterator iter = resolver.resolve(query);

		boost::asio::socket_base::broadcast option(true); // Socket option to permit broadcast messages

		socket_.set_option(option);
		endpoint_ = *iter;
	}

	~UDPClient()
	{
		socket_.close();
	}

	void send(const std::string& msg) {
		socket_.send_to(boost::asio::buffer(msg, msg.size()), endpoint_);
	}

	bool isOpen()
	{

		if(socket_.is_open())
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	void connect_handler(const boost::system::error_code &error )
	{
		if(!error)
		{
			cout << "Everything went well" << endl;
		}
		if(error)
		{
			cout << "Something went wront" << endl;
		}
		else
		{
			cout << "nothing returned" << endl;
		}
	}

	void write_handler(const boost::system::error_code& error, std::size_t byte_transferred)
	{
		if(!error)
		{
			cout << "Everything went well" << endl;
		}
		if(error)
		{
			cout << "Something went wront" << endl;
		}
		else
		{
			cout << "nothing returned" << endl;
		}
	}

	void sendToServer(string scannerAddress, int port)
	{
		boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(scannerAddress),port);
		socket_.async_connect(endpoint,boost::bind(&UDPClient::connect_handler,this,boost::asio::placeholders::error)); //async connect to server
		int data[3] = {-1,-1,17230};
		socket_.async_send(boost::asio::buffer(data),0, boost::bind(&UDPClient::write_handler,this, boost::asio::placeholders::error,sizeof(data))); //async send to server

	}

private:
	boost::asio::io_service& io_service_;
	udp::socket socket_;
	udp::endpoint endpoint_;
};


int main()
{
  int state = OPEN_UDP_PORT;
	string scannerAddress = "10.48.37.183";

  boost::asio::io_service io_service;
	UDPClient client(io_service, "localhost", "5337" ); // Client created;

	while(true)
	{
  		switch (state)
			{
    		case OPEN_UDP_PORT:
    		{
          	cout << "hello world" << endl;
	  				if(client.isOpen())
	  				{
							cout << "UDP connection open!" << endl;
							state = SEND_DATA_TO_SERVER;
	  				}
	  				else
          	{
							cout << "UDP connection is not open!" << endl;
							state = ERROR_HANDLING;
          	}
          	break;
    		}

    		case SEND_DATA_TO_SERVER:
    		{
          	//cout << "Send data to server" << endl;
						client.sendToServer(scannerAddress,9008);
          	break;
    		}
    		case RECEIVE_ANSWER_FROM_SERVER:
    		{
          	cout << "hello world" << endl;
    	  		break;
    		}
    		case RECEIVE_DATA:
    		{
	  				cout << "hello world" << endl;
          	break;
    		}
    		case CLOSE_UDP_PORT:
    		{
          	cout << "hello world" << endl;
    	  		break;
    		}
    		case ERROR_HANDLING:
    		{
          	cout << "hello world" << endl;
    	  		break;
    		}
  		}
		}

return 0;
}


The Idea is that i have to sent some init data to the SERVER, The server responds when that information has been received, but it doesn't seem like that the cline even send any data to the server, as the handler doesn't return anything..

What could be wrong?
boost.asio docs have a number of tutorials, including UDP echo clients, http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/example/cpp11/echo/blocking_udp_echo_client.cpp is an example.

The main problem in your program is that you did not supply ASIO with any threads for its thread pool, and yet you're requesting async operations and offering it handers to run on the pool when the operations complete. Nevertheless, your example successfully floods the UDP server listening at scannerAddress IP, on port 9008 on my machine, with repeating byte pattern ff ff ff ff ff ff ff ff 4e 43 00 00: each pass through the main loop executes one send and queues up one handler to run (which never happens).

Also note that there is no such thing as "UDP connection", so async_connect/async_send looks very weird. Just use async_send_to (or send_to, what's the use of async here?)
In the example you have given from http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/example/cpp11/echo/blocking_udp_echo_client.cpp

It doesn't seem like it connect to the server..

I have it on a local network..
sender_endpoint is never set..
It's UDP, there is no such thing as "connecting". Only sending and receiving. (well, you can "connect", but all it does is record the peer address, no bytes are exchanged on the network)

sender_endpoint is the out-parameter of udp::socket::receive_from, as you can see in its documentation: http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/basic_datagram_socket/receive_from/overload1.html
Last edited on
so in my case i know that my server is located on a local network with the address 10.0.0.53 port 3008.

but the server respond to a port 5009...

how to make sure that send to that and receive/listen on that port...
I am bit confused by the documentation and the usage of it...
DrJones wrote:
how to make sure that send to that

that's why udp::socket::send_to takes an endpoint: http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/basic_datagram_socket/send_to/overload1.html

DrJones wrote:
and receive/listen on that port

that's why udp::socket constructor takes an endpoint: http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/basic_datagram_socket/basic_datagram_socket/overload3.html
Just to understand to it precisely.. This is based from the example..



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//
// blocking_udp_echo_client.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::udp;

enum { max_length = 1024 };

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 3)
    {
      std::cerr << "Usage: blocking_udp_echo_client <host> <port>\n";
      return 1;
    }

    boost::asio::io_service io_service;

    udp::socket s(io_service, udp::endpoint(udp::v4(), 5009)); // Creates an UDP HOST which broadcast, and is on port 5009. 

    udp::resolver resolver(io_service);  // UDP constructor
    udp::endpoint endpoint = *resolver.resolve({udp::v4(), argv[1], argv[2]}); //  Provide send option..  Server IP and Port. 

    std::cout << "Enter message: "; // Send message
    char request[max_length]; // char array
    std::cin.getline(request, max_length); // save message into request
    size_t request_length = std::strlen(request); // length of request
    s.send_to(boost::asio::buffer(request, request_length), endpoint); 

    char reply[max_length]; // reply array
    udp::endpoint sender_endpoint(boost::asio::ip::address::from_string("10.0.0.53"),3008);  // read reply from address 10.0.0.53 and port 3008. 
    size_t reply_length = s.receive_from(
    boost::asio::buffer(reply, max_length), sender_endpoint); // read reply
    std::cout << "Reply is: "; // cout out reply
    std::cout.write(reply, reply_length); // cout reply
    std::cout << "\n";
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n"; // exepction.. 
  }

  return 0;
}


So since i send a message to the server at IP 10.0.0.53 port 3008, so argc[1] = 10.0.0.53 and argc[2] = 3008.
Last edited on
Topic archived. No new replies allowed.