Boost Socket/Acceptor cannot listen/connect on same port? - c++

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()

Related

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 asio - udp server

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

Problem using Connect(), send(), recv, with UDP sockets

For my Uni assignment I have to create a fast action paced networked game and so have chosen to use UDP as opposed to TCP. I am aware of a lot of the differences in programming both UDP and TCP and have read through most of the relevant parts of MSDN's documentation on winsock. On MSDN it states that creating a UDP socket via the connect() function should bind the socket to the address and port specified and as a result be able use the send() and recv() functions with the created socket.
For my application I create a client and use connect() using the loopback address which sends a number of packets via the send() function. The client, after calling select(), then receives the packets it sent out. However the result I get from the recv() function is SOCKET_ERROR and the error description using WSAGetLastError() is "An existing connection was forcibly closed by the remote host".
If i use the bind() function and use sendto() to send data over the loopback address, I recv() packets without any errors... Does anyone know why the connect() function is not doing what it is supposed to do, and has anyone been able to use UDP sockets with the connect() function?
You will need to call bind() if you want your program to receive UDP packets. connect() only sets the address that the socket will send packets to if you call send(); it does not associate the socket with a local UDP port to receive on; for that you must call bind().
"UNIX Network Programming" points out that a connect call made on a UDP client side socket figures out and stores all the state about the destination socket address in advance (masking, selecting interface, etc.), saving the cost of doing so on every ::sendto call. This book claims that ::send vs ::sendto can be up to 3x faster because of this reduced overhead - data can go straight to the NIC driver bypassing most IP stack processing. High performance game programmer's may want to consider this.
you should check Beej's Guide to Network Programming Using Internet Sockets, there are nice examples that address your question.
Keep in mind that the UDP protocol is a "connectionless" protocol meaning that you never ever connect to the host, you just send out data. So you can see that connect as an action is meaningless for UDP.
For UDP you should use sendto() and recvfrom() in these function you specify the address and the buffers and that's about it, everything else that is comfortably handled for you in TCP is gone you have to handle things on your own.
In the MSDN documentation its mentioned that you can in fact somehow use the normal send/recv functions with UDP but why would you when you have separate functions already? Like other commented already connect() for UDP does something else it's not essentially a "connect" operation but a sort of a filter to set up send()/recv() for UDP usage.

Multithreaded Server Issue

I am writing a server in linux that is supposed to serve an API.
Initially, I wanted to make it Multi-threaded on a single port, meaning that I'd have multiple threads working on various request received on a single port.
One of my friends told me that it not the way it is supposed to work. He told me that when a request is received, I first have to follow a Handshake procedure, create a thread that is listening to some other port dedicated to the request and then redirect the requested client to the new port.
Theoretically, it's very interesting but I could not find any information on how to implement the handshake and do the redirection. Can someone help?
If I'm not wrong in interpreting your responses, once I create a multithreaded server with a main thread listening to a port, and creates a new thread to handle requests, I'm essentially making it multithreaded on a single port?
Consider the scenario where I get a large number of requests every second. Isn't it true that every request on the port should now wait for the "current" request to complete? If not, how would the communication still be done: Say a browser sends a request, so the thread handling this has to first listen to the port, block it, process it, respond and then unblock it.
By this, eventhough I'm having "multithreads" , all I'm using is one single thread at a time apart from the main thread because the port is being blocked.
What your friend told you is similar to passive FTP - a client tells the server that it needs a connection, the server sends back the port number and the client creates a data connection to that port.
But all you wanted to do is a multithreaded server. All you need is one server socket listening and accepting connections on a given port. As soon as the automatic TCP handshake is finished, you'll get a new socket from the accept function - that socket will be used for communication with the client that has just connected. So now you only have to create a new thread, passing that client socket to the thread function. In your server thread, you will then call accept again in order to accept another connection.
TCP/IP does the handshake, if you can't think of any reason to do a handshake than your application does not demand it.
An example of an application specific handshake could be for user authentication.
What your colleague is suggesting sounds like the way FTP works. This is not a good thing to do -- the internet these days is more or less used for protocols which use a single port, and having a command port is bad. One of the reasons is because statefull firewalls aren't designed for multi-port applications; they have to be extended for each individual application that does things this way.
Look at ASIO's tutorial on async TCP. There one part accept connections on TCP and spawns handlers that each communicate with a single client. That's how TCP-servers usually work (including HTTP/web, the most common tcp protocol.)
You may disregard the asynchronous stuff of ASIO if you're set on creating a thread per connection. It doesn't apply to your question. (Going fully async and have one worker-thread per core is nice, but it might not integrate well with the rest of your environment.)