2
votes

I have a server class with will start two threads, one is to accept all the incoming connection and put those sockets into a vector. Another one is to scan through this socket vector and find out which one is read to be read/write and then do something.

So the problem is that in the second thread (member function), how do I actually scan those sockets?

people suggest using select() of unix socket but i have decided to use boost everywhere, so I am looking for solution in boost.

I have read some documentation from boost.org and this site. People said that io_service is abstract of select. I don't understand. Do i just bind the function/objects and then use io_service::post() put them into the queue and use io_service::run() to execute?


update, in my understanding, every time you instantiate a new socket object with a constructor including a io_service object, this socket object is associate with the io_service object, since I only have one io_service object, these socket object will be executed when I call io_service.run()

but, the question is, how do i assign handle_function to those socket, I saw people use acceptor.async_accept(socket, boost::bind(handler, &socket)) like this, But I want to use accept rather than async_accept(), but the accept() function cant be used to bind a handler function to this socket

what should i do?

class Server
{
  io_service IOService;

  std::vector<boost::....::socket> SocketVector;

  listen()

  {
    //blockingly accept all incoming connection and bind socket with handler function;
  }

  process HandleRequest()
  {
    //io_service.run()
  } 
}

int main()
{
    Server myServer;
    boost::thread thread1(&Server::listen, &myServer);
    boost::thread thread2(&Server::HandleRequest, &myServer);
}
1
This's of course not an answer, but it seems that you're going the wrong way: you've already got "fixed" on some design (threading, socket polling etc), and now you're trying to "stretch" this scheme onto Boost.Asio. Finally, you'll end up with a horrible design that doesn't fit the tools you've selected. Instead, it's worth reading Asio manual and the related resources (blog.think-async.com) thoroughly and trying to "think asynchronously". This way you'll get much better design that would exploit Asio capabilities. - Igor R.
Thank you Igor, My design is I have one thread listening and one thread select from those sockets and handle them. The reason is that clients need to be connected for a long time but only every few request will be sent. So I dont need a single thread for each connection, instead, I just need one thread for all connection, thus I need something scan those sockets and find which one is availbale[io_service.run()] - cynric4sure
I dont know whether my design is good or not, please suggest other approach - cynric4sure
You don't need to "scan" sockets, and you don't need threads, besides the one that runs the main asio loop io_service::run() (though you can use threads for scalability reasons). With the async (proactor) approach you get notified by means of a completion-handler whenever an i/o-related event occurs, i.e. when a socket gets accepted, when data arrives etc. boost.org/doc/libs/1_53_0/doc/html/boost_asio/overview/core/… - Igor R.
I am try to understand. Did you mean that if I use async_accpet(Socket, boost::bind(&handler, &Socket)) and after that I simply call io_service.run() so I can solve it? - cynric4sure

1 Answers

0
votes

Your design sounds overly complex and will likely not integrate well with Boost Asio. Yes you could use a thread for every socket, but that falls apart quickly when there are more than a handful of concurrent connections.

I suggest rethinking your design and base it around async operations. Study the examples included in the asio documentation. There is also plenty of information in the tag.