boost::asio sync server is not accepting connections after first one - c++

I am writing simple synchronous asio server.
Workflow is following - in endless cycle accept connections and create thread for each connection. I know, this is not so optimal, but async is too hard for me.
Here's my ugly code:
std::vector<asio::io_service*> ioVec;
std::vector<std::thread*> thVec;
std::vector<CWorker> workerVec;
std::vector<tcp::acceptor*> accVec;
while (true) {
ioVec.emplace_back(new asio::io_service());
accVec.emplace_back(new tcp::acceptor(*ioVec.back(), tcp::endpoint(tcp::v4(), 3228)));
tcp::socket* socket = new tcp::socket(*ioVec.back());
accVec.back()->accept(*socket);
workerVec.push_back(CWorker());
thVec.emplace_back(new std::thread(&CWorker::run, &workerVec.back(), socket));
}
The problem is first connection being done, it's correctly accepted, thread is created, and everything is good. Breakpoint is correctly triggered on "accept()" string. But if I want to create second connection (it does not matter if first is DCed or not) -> telnet is connected, but breakpoint on next string to "accept" is not triggered, and connection is not responding to anything.
All this vector stuff - I've tried to debug somehow to create separate acceptor, io_service for any connection - not helped. Could anyone point me where is error?
P.S. Visual Studio 2013

The general pattern for an asio-based listener is:
// This only happens once!
create an asio_service
create a socket into which a new connection will be accepted
call asio_service->async_accept passing
the accept socket and
a handler (function object) [ see below]
start new threads (if desired. you can use the main thread if it
has nothing else to do)
Each thread should:
call asio_service->run [or any of the variations -- run_one, poll, etc]
Unless the main thread called asio_service->run() it ends up here
"immediately" It should do something to pass the time (like read
from the console or...) If it doesn't have anything to do, it probably
should have called run() to make itself available in the asio's thread pool.
In the handler function:
Do something with the socket that is now connected.
create a new socket for the next accept
call asio_service->async_accept passing
the new accept socket and
the same handler.
Notice in particular that each accept call only accepts one connection, and you should not have more than one accept at a time listening on the same port, so you need to call async_accept again in the handler from the previous call.
Boost ASIO has some very good tutorial examples like this one

Related

Why does my Winsock app sometimes wait at listen() and sometimes at accept()?

Hey guys I'm using Visual C++ 2010, trying to write a server/client app using Winsock... I'm not sure why, but sometimes the server waits at the listen() function, and sometimes at the accept(). Just wondering, what is the mechanism of these two functions? Isn't it supposed to wait at listen() until it hears an incoming connection and then proceed to accept()?
The listen function puts the socket into listening mode. You have to call this functions only once. Normally, this function returns immediately.
The incoming connections are accepted by calling accept function. In the blocking mode (default) it returns only when a new connection is accepted or an error occurs.
It doesn't. Your observations are faulty. listen() is not a blocking call. All it does is put the port into LISTENING state, and that either succeeds or it fails. There's nothing to block for.
It is accept() which blocks, waiting for an inbound connection.

Why does writing to this socket discard the read buffer (and is that really what's happening)?

Consider the following snippet:
QTcpServer server;
server.listen(QHostAddress::LocalHost);
QTcpSocket clientSocket;
clientSocket.connectToHost(server.serverAddress(), server.serverPort());
// ...wait for connection to succeed...
QTcpSocket *serverSocket = server.nextPendingConnection();
serverSocket->write("test");
serverSocket->close();
The goal of this snippet is to create two connected sockets by creating a QTcpServer that listens for incoming connections and connecting to it with another QTcpSocket. Once the connection is established, data is written to one of the sockets and it is closed.
QAbstractSocket::close() invokes disconnectFromHost() The documentation for QAbstractSocket::disconnectFromHost() clearly states that:
If there is pending data waiting to be written, QAbstractSocket will enter ClosingState and wait until all data has been written.
The next snippet enters the event loop briefly to process pending events and then attempts to read the string from the other socket:
QCoreApplication::processEvents();
qDebug() << clientSocket.readAll();
This prints "test" and all is well. Or perhaps not. If I modify the previous snippet by prepending a call to write(), the data can no longer be read from the socket:
clientSocket.write("test");
QCoreApplication::processEvents();
qDebug() << clientSocket.readAll();
This prints an empty string ("") instead of the expected value from the previous run. Why can't the socket read the value this time?
Note: this only manifests itself on the Windows platform. Neither Linux nor Mac OS X builds of Qt exhibit this behavior, instead printing the expected value in both cases.
Second note: if you want to play with the code, there's a working Gist here: https://gist.github.com/nathan-osman/ee6116d120903db84384
Third note: here's a screenshot of a Wireshark capture of the TCP exchange:
Im not very familiar with Qt, but on Windows, there is no Fork. You are trying to fit to parallel tasks on the same thread, but you should have the client running on a different thread than the server.
You're writing asynchronous code in synchronous style in a way that doesn't ensure that you wait long enough for things to happen. Calling processEvents simply means "do any work that is currently available to do" not "do work and/or wait for work until no more work can possibly arrive". You treat it like the latter, but it means the former.
The simplest fix is not to do that.
Connect slots or functors to relevant socket signals, and return control to the event loop. Never use waitForXxx functions, they simply aren't specified sufficiently to allow use in all cases. Never mind the horrible reentrancy issues you'll face when reentering the event loop.
If there's no event loop in the thread where your code runs, spin up your own:
QEventLoop loop;
...
connect(serverSocket, &QAbstractSocket::disconnected,
&loop, &QEventLoop::quit);
loop.exec(); // this will keep executing until the socked is disconnected

Multithread server in C++, how to terminate threads and clean up nicely

The server I've written in c++ server works like proxy. Main function:
try
{
Connector c(ip); //establishes persistent connection to the server B
Listener1 l1(port); //listens incoming connection to the server A (our proxy) and push them into the queue
Listener2 l2(&c); //listens responses (also push messages) from the server B and push them into the queue
Proxy p(&c, &l1, &l2); //pulls clients out from the queue and forwards requests to the server B, pull out everything from the listener2 queue and returns as a responce
KeepAlive k(&l1, &p); //pushes the empty client to the listeners1's queue thus the proxy sends keepalive to the server B and the response is discarded
l1.start();
p.start();
l2.start();
k.start();
l1.join();
p.join();
l2.join();
k.join();
catch(std::string e)
{
std::cerr << "Error: " << e << std::endl;
return -1;
}
For now I have problems/doubts as follows:
**1.**I throw an exception from constructors, is it good practise? I throw an exception when it's not possible to establish the connection, that's why the object shouldn't be created I guess.
**2.**There is a problem with closing the application safety and clean up when the connection time-out occurs or the server B closes the connection and so on. listener1 and listener2 use blocking functions (system call accept() and BIO_read from openssl lib) so it's not possible to just set the loop condition from another thread. The problem is also the fact that all the modules are connected and share resources using mutexes. My current piece of code just calls exit function to terminate whole application.
I know this is not a perfect solution, I appreciate any advices and tips.
Thanks in advance
Constructors should throw exceptions if they fail. C++ is designed to handle that well. Base classes and members are cleaned up if and only if they're already constructed.
Blocking functions from other libraries are always a problem. Windows and POSIX handle it well: WSAWaitForMultipleObjectEx and select allow you to add an extra handle, which you can use to unblock the wait.
In your accept call, you might fake this by creating a connection from the main thread, via localhost. Detecting this "unusual" connection would be a signal to stop accepting further connections.
As for the openSSL read, I'd just close the socket from the main thread, threadsafety be damned. I would make sure that I'd do this quite late in the shutdown, and I wouldn't expect the library to be usable at all after that point.

How do I get an OpenSSL server using blocking BIO to shutdown cleanly?

In a larger server app I have one thread with a basic OpenSSL server using BIO in blocking mode because that seemed the simplest way. My code accepts a single type of request from a phone (Android or iOS, and I'm not writing that code) and returns a hex string wrapped in basic HTML (describing part of my server state). I've gone with SSL and a psuedo-HTTPS server because that makes things easier for the phone developer. If there's anything in the request that the server doesn't understand I return a 404. This all works.
The problem : When my server shuts down this thread doesn't exit because of the blocking BIO_do_accept call.
I have tried BIO_get_fd() and setsockopt() to put a timeout on the underlying socket but it still blocks. Somewhat worryingly SSL_state() stays at "before/accept initialization", but looping on that obviously won't work.
I assume other people have server code like this, and those servers can shut down gracefully. How do they do that? Is there some way for another thread to break that block and get the accept call to return with an error? Or do I have to drop the idea of blocking calls and grind through the apparently awful non-blocking version?
When my server shuts down this thread doesn't exit because of the blocking BIO_do_accept call.
To stop the blocking, close the associated socket. It will return immediately.
Perform the shutdown from your signal handler.
Don't do anything else in the signal handler with respect to OpenSSL because it is not async-signal safe. Let the main thread cleanup once your worker thread has returned. See, for example, libcrypto Thread Safety.

C++ Can I make boost::asio connection socket without timer?

I have a window server socket and a Linux client socket. Client connect to server and send a message. After, the server will call a external executable. The problem is : when server is not available, Client is blocking with timeout at connect function, But I don't want it. I hope if the connection is not made, client socket will be closed straight away.
Somebody can give me some advice?
Warning: Pseudo-Code ahead.
You can do that. But it is not as straight forward as you might hope.
You need to use async_connect() from your client to not block. Then you also need a deadline_timer set to whatever timeout you deem appropriate. Zero will not work, you need to give the async_connect() some time. But i guess one or two seconds should be fine.
The timers handler will then have to cancel() all async operations on the socket (you need to make sure that is only the connect, use more sockets if needed).
Mind the socket will not be closed by that. Ideally you will close it in the handler of the async_connect whenever the passed error_code indicates a negative result. For example, if it was canceled, the handler will be called with OPERATION_ABORTED as error_code.
Of course, if you check only for that, you could as well close() the socket in the timers handler after the cancel(). But that would leave you with an open socket whenever the async_connect failed for some other reason.
I would assume from your question that you want your socket to get closed whenever the async_connect() passes any error_code but SUCCESS. And SUCCESS is the only error_code implicitly converted to 0 when used as a boolean, so checking for that in your handler is easy. ^^
Do not forget to cancel the deadline_timer in the handler of the async_connect() and to make sure the timers handler was not called with OPERATION_ABORTED before it closes the socket. ^^