Boost asio - udp server - c++

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.
EDIT
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.

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

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.

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 same udp socket for async receive/send

Related

Boost.Asio - How to send a message to multiple clients

I have been looking at a lot of Boost.Asio tutorials, especially this one:
TCP daytime server
After a server creates a tcp_connection with a client, it seems like the communication is only one-way between the server and that specific client. How can I make it so a server has the ability to relay client messages to all of the clients connected? Or even choose which clients to send messages to.
TCP create only connexion between the server and a specific client. You can use UDP connexion to broadcast message to several clients.
Like JTejedor says in comments, you can also create a TCP socket for each client.

boost::asio::tcp two-way communication on a socket

I am using boost::asio, TCP communication and C++ to create a client and a server that talk over a TCP socket. I need both the client and the server to be able send and receive data to each other. I am able to make them communicate over a socket where the server is continuously sending some data and the client is continuously reading on the socket. It works.
Now for the other way communication : For client to send some data and the server to be able to read it, can I use the same socket for this? Or Do I need to use a separate socket? Is it possible to read and write on the same socket for two applications communicating over TCP?
A boost::asio based example to illustrate this will be great if available. But I am able to find examples which are about only one-way communications.
For client to send some data & server to be able to read it, can I use the same socket for this? Or Do I need to use a separate socket ? Is it possible to read and write on the same socket for two applications communicating over TCP ?
Yes. TCP is full duplex. Applications define the protocol of what/how messages are exchanged between client and server. Weather they do asynchronously or synchronously, TCP doesn't care.
The client server paradigm in tcp is one where the client initiates the connection and the server listens for incoming connections. Once tge connection is established, it is up to higher layer protocol like http to establish how data is exchanged. As far as tcp is concerned both client and server may send or receive data any way they choose. Tcp is full duplex.

Winsock ~ Creating an UDP Listener (Multiple vs 1 socket)

Dear Stackoverflowers,
I am researching networking a bit and I decided I'd like to create a small and simple networking library with Winsock. (I am using Completion Ports and Overlapped IO though)
As I researched a bit I came to the following steps for a TCP Listener(Correct me if I am wrong):
Create a Listening Socket
Bind it to a port/IP
Listen on it
When a new connection is created, give a seperate Socket for that connection.
Listener continue's to listen, the specific connection is handled as needed.
EDIT: With a 'connection' from here I mean communication between the server and distinct clients.
Though for an UDP Listener we need to make use of WSARecvFrom which returns the IP address at the lpFrom parameter. Now I was wondering the following:
Is it better to make one UDP Socket listen to incoming connections on a specific port with WSARecvFrom and create new sockets for every specific connection? Or could I just use the UDP Socket itself with WSASendTo. Would that cause any performance penalties if one UDP Socket is used for for example 1000 connections? Or would it be the same or even better then creating/duplicating seperate Sockets for each different incoming connection?
Note: If multiple sockets are needed how would you handle sockets listening on the same port or could a client accept UDP from different ports?
Hope you guys can help!
Ps. Extra tips are always welcome!
Unlike TCP, UDP is connection-less, and as such you don't need to create separate sockets for each party. One UDP socket can handle everything. Bind it to a local IP/Port and call WSARecvFrom() once, and when it reports data to your IOCP you can process the data as needed (if another thread if needed) and then call WSARecvFrom() again. Each time new data arrives, you have to look at the reported lpFrom address to know the IP/Port of the sender. And yes, you can use the same UDP socket for sending data to each sender when needed.

Boost Socket/Acceptor cannot listen/connect on same port?

I am a bit new to Boost, but I am trying to create a Server that can accept connections from a client on a given port. This Server should also be able to write to the client on the same port.
However, when I attempt to implement both using acceptor_.bind()/acceptor_.listen() as well as socket_.connect(*iterator) the async_accept() fails with an invalid function error.
If I only use acceptor_.bind(), acceptor_.listen() I am able to write to the socket (from the Server to the Client) using async_write().
If I only use socket_.connect() (but comment out the acceptor_.bind(), acceptor_.listen()) I am able to read from the socket (data sent from Client to Server) using async_read_some().
Do I need to create a separate socket object or choose another port? I have reuse address enabled set to True.
Why are you trying to connect() to a client that is already connected to your server? Just write to the existing socket that was accepted for that connection.
If you must connect() a second connection to a client (for example, like the FTP protocol does for data transfers), then don't specify a port to bind that socket to. Let the OS decide a suitable port to use.
It seems to be you haven't grasped some basic concepts of network programming, this is unrelated to boost or the Asio library. Generally speaking, servers invoke accept() and clients invoke connect(). The asio examples show this in detail, see
async tcp echo server
blocking tcp echo client
And note that the server invokes
async_accept()
async_read_some()
async_write()
whereas the client invokes
connect()
write()
read()

SOCKS 5 and UDP (C/C++)

I know that SOCKS 5 supports UDP and I have been over the structure of the packets that are sent/received in negotiating with a SOCKS proxy.
The one thing I am not clear on is the procedure for setting up to register with a proxy to send/receive UDP packets.
Specifically, my biggest question is, "Is the connection to the SOCKS proxy that is used to negotiate a UDP associate relationship still made with TCP/IP?". In other words, "Do you end up using a TCP/IP socket to receive UDP packets routed through a SOCKS proxy?"
I would imagine that, if you used a TCP/IP connection to establish a pathway for UDP communication, you'd kind of be missing the whole point of establishing UDP communications. However, on the other hand, if the negotiation were made using UDP (and resulted in a UDP socket), then how would the relationship be terminated when your application is shutting down and no longer needs the proxy to "remember" you?
I have been all over the net looking for an example...but can't find anything. Any help (especially an example) would be appreciated.
https://www.rfc-editor.org/rfc/rfc1928
"A UDP-based client MUST send its datagrams to the UDP relay server at
the UDP port indicated by BND.PORT in the reply to the UDP ASSOCIATE
request"
but
"UDP association terminates when the TCP connection that the UDP
ASSOCIATE request arrived on terminates."
I actually tried using it once, but failed, because many "socks5" proxy
implementations don't actually support the complete protocol.
So I'd suggest to set up a working test case first (find an app which
would support socks5 udp proxy, and a proxy where it would actually work).
Then any network sniffer would tell you how it really works (if it does).