Need aid with boost asio sockets please

Hello!

I'm trying to create code that reads from and writes to multiple clients/devices using boost sockets, but I'm not exactly sure if I'm doing it correctly. There seems to be a lack of documentation for asio, and I was wondering if anyone here could help.

Essentially, I want the code to be constantly listening for data and be able to read it (256 characters or less) and process it accordingly.

I also want to be able to make a call to write back to the client on an open socket. It seems to kind of work, although I'm having a few issues with destructors and writing data, not too sure what I should be doing and when. Would anyone mind having a look at the code to tell me what I'm doing wrong? I've modified it from the example that they provided on the boost website. Thanks!

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
#include "CentralServer.h"


session::session(boost::asio::io_service& io_service) : socket_(io_service)
{
}

void session::startReading()
{
	socket_.async_read_some(boost::asio::buffer(data_, max_length),
		boost::bind(&session::handle_read, this,
		boost::asio::placeholders::error,
		boost::asio::placeholders::bytes_transferred)
		);
}

void session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
	if (!error)
	{
			printf("Reading Data of length %ld: %s \n",bytes_transferred,data_+1);
			strncpy(deviceID_,data_+1,4); // store the device ID (Characters 2-5 of data_)
			int i = atoi(deviceID_);
			deviceLookup.insert(std::make_pair(i,this));


		/*boost::asio::async_write(socket_,
			boost::asio::buffer(data_, bytes_transferred),
			boost::bind(&session::handle_write, this,
			boost::asio::placeholders::error)
		);*/

		startReading(); // do I want to call read_some again? I seem to need to...
	}
	else
	{
	  delete this;
	}
}

void session::handle_write(const boost::system::error_code& error)
{
	if (!error)
	{
		//do nothing here? Not sure if I need to really handle anything after data is written
	}
	else
	{
		//delete this; // probably don't want to delete the session?
	}
}

// ##################################################################################################//
// #################################### Server Functions ############################################//
// ##################################################################################################//

server::server(boost::asio::io_service& io_service, short port)
    : io_service_(io_service), acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
{
	session* new_session = new session(io_service_);
	
	acceptor_.async_accept(new_session->socket(),
		boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)
	);
}

void server::handle_accept(session* new_session, const boost::system::error_code& error)
{
	if (!error)
	{
		printf("New session\n"); 
		new_session->startReading();
		new_session = new session(io_service_);
		acceptor_.async_accept(new_session->socket(),
			boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)
		);
	}
	else
	{
		delete new_session;
	}
}


//function called from another class which needs to write data to a client

int server::writeToDevice(char* buffer, int dataLength, int deviceID)
{
	std::map<int,session*>::iterator iter;

	iter = deviceLookup.find(deviceID);
	if(iter != deviceLookup.end()) // check if the device is currently connected
	{
		session* mysession = iter->second;


                //write one byte telling the length of the next packet of data
		boost::asio::async_write(mysession->socket(), 
			boost::asio::buffer((char*)dataLength, 1),
			boost::bind(&session::handle_write, mysession,
			boost::asio::placeholders::error)
		);

		//write to the device with data in buffer
		boost::asio::async_write(mysession->socket(), 
			boost::asio::buffer(buffer, dataLength),
			boost::bind(&session::handle_write, mysession,
			boost::asio::placeholders::error)
		);
	}
	else
	{
		//cannot write to device if it isn't connected
		return -1;
	}
	return 0; //OK
}



Class definitions, not that important
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
#include <cstdlib>
#include <iostream>
#include <map>

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/array.hpp>


#define _WIN32_WINNT 0x0501

//using boost::asio::ip::tcp;

class session
{
private:
	boost::asio::ip::tcp::socket socket_;
        enum { max_length = 1024 };
        char data_[max_length];
        char deviceID_[4];
 
public:

	session(boost::asio::io_service& io_service);
	boost::asio::ip::tcp::socket& socket()
	{
		return socket_;
	}
	
	char * data()
	{
		return data_;
	}

	char *deviceID()
	{
		return deviceID_;
	}

	void startReading();
	void handle_read(const boost::system::error_code& error, size_t bytes_transferred);
	void handle_write(const boost::system::error_code& error);
};

class server
{
public:

  server(boost::asio::io_service& io_service, short port);

  void handle_accept(session* new_session, const boost::system::error_code& error);
  int writeToDevice(char* buffer, int dataLength, int deviceID);

private:
  boost::asio::io_service& io_service_;
  boost::asio::ip::tcp::acceptor acceptor_;
  
};

static std::map<int, session*> deviceLookup;
Topic archived. No new replies allowed.