Problem with boost

I been working on a server via boost networking and can't get it to work:
hers my code:
server.h:
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
#ifndef SERVER_H
#define SERVER_H

#ifdef WIN32
	#define _WIN32_WINNT 0x0501
#endif
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <map>

class Client;

typedef boost::shared_ptr<Client> ClientPtr;
typedef std::map<boost::asio::ip::tcp::socket, ClientPtr> ClientsMap;

class Server
{
	public:
		Server();
		~Server();

		void start();

		void setAcceptConnections(bool);
		bool acceptConnections();

		ClientsMap::const_iterator begin() { return m_clients.begin(); }
		ClientsMap::const_iterator end() { return m_clients.end(); }

		int size() { return m_clients.size(); }

	private:
		ClientsMap m_clients;
		bool accept_connections;
		boost::asio::io_service service;
		boost::asio::ip::tcp::acceptor* m_acceptor;
};
#endif 

server.cpp:
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
#include "server.h"
#include "defines.h"
#include "client.h"

Server::Server()
{
	accept_connections = false;
}

Server::~Server()
{
	m_clients.clear();
}

void Server::setAcceptConnections(bool accept)
{
	if (accept_connections == accept)
		return;

	accept_connections = accept;
}


void Server::start()
{
	m_acceptor = new boost::asio::ip::tcp::acceptor(service, boost::asio::ip::tcp::endpoint(
		boost::asio::ip::tcp::v4(), SERVER_PORT));
}

bool Server::acceptConnections()
{
	boost::asio::ip::tcp::socket newSocket(service);
	m_acceptor->accept(newSocket);
	ClientPtr ptr(new Client(newSocket));
	ClientsMap::const_iterator p = m_clients.find(newSocket);
	if (p == m_clients.end())
		m_clients[newSocket] = ptr;
}

error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h: In member function `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >]':
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:1104:   instantiated from `typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) [with _Key = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, _Val = std::pair<const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, ClientPtr>, _KeyOfValue = std::_Select1st<std::pair<const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, ClientPtr> >, _Compare = std::less<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, _Alloc = std::allocator<std::pair<const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, ClientPtr> >]'
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:498:   instantiated from `typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const _Key&) [with _Key = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, _Tp = ClientPtr, _Compare = std::less<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, _Alloc = std::allocator<std::pair<const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, ClientPtr> >]'
server.cpp:35:   instantiated from here
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:227: error: no match for 'operator<' in '__x < __y'
D:/Dev-Cpp/include/boost/asio/ip/basic_endpoint.hpp:275: note: candidates are: bool boost::asio::ip::operator<(const boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>&, const boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>&)
D:/Dev-Cpp/include/boost/asio/ip/address.hpp:232: note:                 bool boost::asio::ip::operator<(const boost::asio::ip::address&, const boost::asio::ip::address&)
D:/Dev-Cpp/include/boost/asio/ip/address_v6.hpp:316: note:                 bool boost::asio::ip::operator<(const boost::asio::ip::address_v6&, const boost::asio::ip::address_v6&)
D:/Dev-Cpp/include/boost/asio/ip/address_v4.hpp:207: note:                 bool boost::asio::ip::operator<(const boost::asio::ip::address_v4&, const boost::asio::ip::address_v4&)

D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h: In copy constructor `boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_io_object(const boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)':
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:339:   instantiated from `_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, _Tp = ClientPtr, _Compare = std::less<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, _Alloc = std::allocator<std::pair<const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, ClientPtr> >]'

server.cpp:37:   instantiated from here
D:/Dev-Cpp/include/boost/noncopyable.hpp:27: error: `boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)' is private
D:/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:339: error: within this context

make.exe: *** [server.o] Error 1
There are two errors being reported by the compiler.

The first is telling you that the boost::asio::ip::tcp::socket type does not have an operator< defined that
takes another boost::asio::tcp::socket (hence line 35 doesn't compile, because find() will try to call operator<)

The second is telling you that boost::asio::ip::tcp::socket is non copyable, but std::map<>::operator[] requires
that the key type (boost::asio::ip::tcp::socket) be copyable.

What can I do about it?
I've been fighting with the boost library for awhile to, I'm not as far into it as you but I ran into a simular issue with an object that can't\won't do what it is needed to do and was able to work around it with a pointer to the structure. I'm not sure if this will help or if it's completley irrelevent but let us know either way.
Thanks, computergeek81, this worked changed it to "*" pointer
but does that mean the boost::noncopyable failed?
btw i got a small problem, when i try to attempt a connection to it, it exits randomly
Last edited on
From what I have learned using ASIO_Boost the only way to know for sure is to execute it in a test environment. Sorry
I get this error: Exception: The file handle supplied is not valid
I have been using ASIO for a *long* time, and I noticed the issue immediately, but let me describe why I do.

Socket is an OS resource, and for any given socket there is one resource for it (makes no sense for there to be more). Now, all std containers operate by value, and some have stronger requirements, such as map, which of course requires keys to be less-then comparable. Now, trying to use a limited resource means that there is only one instance of that resource, meanin that you cannot copy it (hence the boost::noncomparable error, that part should be obvious based on that error).

Now, you attempted to bypass those built-in protections by taking the address of the socket instead, problem is that its memor location will change based on access patterns since you probably do not have it on the stack anymore. Sockets, however, are shared pointer capable, and that is how they can be accessed other then by value, but even in this case that is not necessary.

Since you did not give a complete test-case (in other words, your code is *very* incomplete, try to give complete compilable cases) I am going to have to hypothesize as to how you access it all. First, you accept an incoming socket, but the only place you 'store' it is as a map key, then it disappears off the stack (hence the resource is then released, wrong lifetime). Second, since the only place it exists (if your code worked) is as the key in the map, you could never look it up, only way you could access it is by iterating over the entire map, which defeats the point of the map in the first place.

Based on what I can only guess that you are doing, and since you are keeping extra state with your sockets, you should create a helper class that has a constructor to take and hold a boost::shared_ptr of your socket, and have your associated data in this struct. You should keep a shared_ptr of your struct too, perhaps in a linked list, and if you want to do async ops, then derive it from shared_from_this too and pass the shared_ptr of itself into the async handler.

I can elaborate further, but the examples demonstrate what I am describing quite well, ask if so and if I can I will respond
Last edited on
Topic archived. No new replies allowed.