impulsar asio - servidor udp

I saw the official async udp server example from boost doc. There you create a single udp socket, bind it to a local port and do something like this:

socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port))

socket.async_receive_from(buffer(data, max_length), senderEndpoint, boost::bind(&Request::HandleReceiveFrom, this,
    boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));

How can I handle multiple concurrent udp connections from clients, because if I try to create another socket using

socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port))

i get bind errors because I already have a socket bound to the same port.

EDITAR I can send clients back responses using a different server source port but they will not recognize the response even though I sent the response back to the same client ip/client destination port.

preguntado el 28 de agosto de 12 a las 09:08

Maybe you should just reuse the existing binding. -

@MarkGarcia on the socket created I would also need to give back replies to the client. There are multiple clients that would receive data on the same socket. -

UDP does not have any connections. If you want connections, you will have to add a connection protocol layer on top of UDP, eg. with a 'Connection' class for each peer and creating a new instance for each new sender that sends a message. -

@MartinJames I use my server as a dns proxy. I want to handle multiple clients, proxy their requests, and give answers back. -

If I could use something as a boost asio tcp acceptor (for UDP this time) I would be able to create different udp sockets for different client requests -

3 Respuestas

UDP is a connectionless transport so the concept of connections is meaningless as far as UDP is concerned.

If you want to send data back to the originator of the message you'll need to keep a copy of the sender_endpoint returned in the async_receive_from callback and pass it back in the async_send_to.

This also assumes that the client is also polling/reading and expecting a reply. It need not listen on the same bound port as the server (you don't need to bind with UDP on the client side).

I recommend you have a read of Beej's guide to network programming to help you understand what's going on under the hood of boost ASIO. Boost ASIO complicates things a lot IMHO.

http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#sendtorecv

Respondido el 10 de Septiembre de 12 a las 04:09

El enlace que proporcionaste está muerto. - user5915738

If your clients send their messages to the same port on your server then the only way to distinguish them is by the remote port or a combination of remote port and remote ip.

You create some sort of mapping from client-id (e.g. pair<remote_ip, remote_port>) to a dispatcher type (e.g map< pair<remote_ip, remote_port>, dispatcher>). This then it's up to you to make it threaded in order to support concurrent requests.

Respondido 28 ago 12, 09:08

So, using boost asio is not necessarily to use the same udp socket that I've received data from a client (that in order to send back data to client). - Ghita

In theory all that counts is that you send to the right IP and the right port number. However, I never tried to send the data back over a different socket then the one it came from. So I am not 100% sure it will work. Update: actually the client will expect the reply to come back from the same server port as the one it sent to. See also esta respuesta. - ApiladoCortado

I can make the mapping remote_ip, remote_port so that to replay to that client, but if I don't use the same source port number when replaying back the client will not recognize my response - Ghita

As it seems the solution can be to use the same socket for sending back responses to clients. Have a look at this question response: Use el mismo socket udp para recibir/enviar asíncrono

contestado el 23 de mayo de 17 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.