mbed socket connection takes a long time - c++

I'm fighting with my Mbed controller and it's winning :/
Part of my code below:
eth.connect();
pc.printf("ethernet OK");
sock.set_blocking(false,200);
pc.printf(" socket setting OK ");
sock.connect("192.168.1.100", 80);
pc.printf("GO! GO! GO!");
conn = sock.is_connected();
When the server is on I can connect with socket and there is no problem. But when I shut my server down, my program wait in sock.connect(...) line for a long time and then it moves forward. I want it to move forward, but I don't want to wait such a long time :/
I found that I should change socket setting from blocking to non-blocking, and timeout from default=1500 to less. I changed it everywhere I could:
- Part of my socket.h library:void set_blocking(bool blocking, unsigned int timeout=200);
- Part of my socket.cpp library:Socket::Socket() : _sock_fd(-1), _blocking(false), _timeout(200)
And still nothing. It wait about 17-18sec, but I would like to change it to max. 1-2sec.
I would be glad, if you give me an any tip :)

Assuming you are using mbed OS, set the socket to blocking and set the timeout to whatever you think is appropriate. No modifications are necessary. The method syntax can be seen here.
However, I am having trouble reproducing your issue. Can you use a debugger and confirm if the application is hanging at this line - https://github.com/ARMmbed/mbed-os/blob/533e6f0febb5ea582a61f0c8aaf686c70333524f/features/netsocket/TCPSocket.cpp#L57?

marshmallow's suggestion should be fine.
Theoretically you could also try and set the TCP_SYNMAXRTX macro to something lower. It might have some other unforeseen consequences though (which I'm not sure off, as I don't know much about LwIP).

Firstly I need to say, that TCP_SYNMAXRTX changing is something, what can really help, it helped me, but not at all. In my case the important was to change mbed OS to the latest version. In previous there was libraries with socket settings, but actually they work properly since mbed OS contains EthernetInterface and others libraries (you shouldn't import it as external library).
Thank you for your time and goodwill! :)

Related

Send call inside Poco C++ library not returning on Windows after running for some time

I have to connect with a Socket.io 0.9 server (for legacy compatibility reasons) from my C++ code. socket.io-poco looks like the only library that provides this functionality, so I have taken the plunge and pulled in Poco in order to support that. Things mostly work, until they do not.
My process seems to stall on a send call. The call inside SocketImpl.cpp does not return, but it takes around half an hour of disconnected execution to get to that state. I am not sure how to prevent and/or recover from the program getting into this bad state.
The program executes on Windows 2012 R2. It connects to the server and converses successfully, but the connection can become volatile. I will come back and the service will be not visible to the server sometimes. This can take hours or days to occur. My test scenario is artificially disconnecting the server and seeing what happens. That normally results in the program getting into this non-returning state in about half-an-hour.
Any ideas for how to mitigate or resolve this issue?
A different C++ library capable of speaking Socket.io 0.9x
Something I can do to the stale socket.io-poco code to make it more defensive
Guesses as to what I or any of the layers in between have messed up?
Any other ideas?
I decided I needed to learn more about Winsock, so I found a guide. That told me to look at setting SO_SNDTIMEO with setsockopt. After searching through SocketImpl.html I found setSendTimeout and found I can call it in the socket.io-poco call using WebSocket.
I then just had to catch the exception and call a new reconnect function when the timeout occurred:
void SIOClientImpl::reconnect() {
// Disconnect
_heartbeatTimer->stop();
_ws->close();
// Connect
if((handshake(_queryArgs)) && (openSocket())) {
connectToEndpoint(_uri.getPath());
} else {
Poco::Thread::sleep(100);
}
}
I don't know which to hope for: that this answer is helpful or that nobody else has to try and do this!

My libevent timer stops as soon as another event occurs... is that normal?

Currently I setup two events:
Listen for new connections from clients (I'm a server)
A timer to run some code once a second to do various background work
On startup the timer works and I can wait as long as I want and my callback gets called over and over again every second just as expected.
However, as soon as I get a client connection, the other even occurs, and somehow the timer stops working. Is there a known bug in the libevent interface or am I possibly misusing the library?
I am using libevent version libevent-2.0-5:amd64 under Ubuntu 14.04.
I added my own C++ interface so showing all the code here would be really large. It can be browsed in the project on SourceForge.net here:
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/lib/snap_communicator.h
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/lib/snap_communicator.cpp
The usage is pretty simple, but again it is pretty large, the complete implementation is found here:
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/lib/snapwebsites.cpp
The important part looks like this:
g_connection = new connection_t;
g_connection->f_communicator.reset(new snap_communicator(priority));
g_connection->f_listener.reset(new listener_impl(this, host[0].toUtf8().data(), p, max_pending_connections, true, false));
g_connection->f_listener->set_name("server listener");
g_connection->f_communicator->add_connection(g_connection->f_listener);
g_connection->f_temporary_timer.reset(new temporary_timer(this));
g_connection->f_temporary_timer->set_name("server timer");
g_connection->f_communicator->add_connection(g_connection->f_temporary_timer);
g_connection->f_communicator->run();
As we can see I add those two "connections" and the timer works just fine until the listener happens. There is only one place where I remove those two connections from the libevent objects and it is NOT hit (I would know I have a log, and yes, the logger works just fine.)
My mistake! The documentation clearly says that you should make your sockets non-blocking. Once I did that, it started working as expected.
My socket was blocking before since I was just calling accept()...
Now I really don't understand why the library has such a limitation, but that was the solution to this question.
I added the following code for the listener:
if(get_socket() != -1)
{
// libevent does not like blocking sockets...
int optval(1);
ioctl(get_socket(), FIONBIO, &optval);
}

Win API serial port need to wait after initialization

I have a following problem. I have a serial port device that is supposed to communicate with a computer. In fact it is Arduino Due board but i don't think it is related.
I use CreateFile to open the port, and then set the parameters using GetCommState()&SetCommState() and GetCommTimeouts()&SetCommTimeouts().
The port is opened correctly - no problem there. But at this point I want to check whether the device is connected. So I send a specific message. The device is supposed to respond in a certain way so that I know it is connected.
Now to the problem: It only works if put Sleep(1000) after Creating the port (before sending the handshake request). It looks as if the WinAPI needs some time before it can begin to use the port. Because the Sleep solution is not generally usable I need to find some alternative...
By it doesn't work I mean ReadFile times out. It times out even if the timeout is set to something like 5 seconds - note that the Sleep interval is only one second. So it looks like the handshake request is not even sent. If I set timeout to 1 second and Sleep interval to one second, it works. If I set timeout to 5 seconds but there's no Sleep it doesn't work. See the problem?
I am going to try some NetworkMonitor, but I'm kinda sure the problem is not with the device...
OK, I might have searched a little more before posting this question.
The thing is that Arduino restarts itself when you open a connection from your PC.
When you use a terminal you connect first and write a few seconds later so that the Arduino board has enough time to boot up and you won't notice the thing. Which is what confused me enough to write the question.
There are 3 solutions to this, only 2 of which it makes sense to mention at all:
1) the solution I used without knowing all this (you wait about a second for the board to boot up again...)
2) you disable auto-reset by modifying your Arduino board
Both of them are stupid if you ask me, there should be a switch or a flash variable to do this...

ctb::SerialPort - time-out in Write()

I'm writing program that should control a piece of scientific hardware over COM-port. The program itself is written in wxWidgets and uses ctb library. To test, it before I connect it to 300k€ equipment, I use com0com (Null-modem emulator) to forward COM2 port. To emulate my hardware I use wxTerminal (COM3). Altogether it works nice. One can debug not only in VS or DB but also see the whole data transfer in wxTerminal.
Now to my problem. I use to send data to COM-port ctb::SerialPort::Write() function.
device->Write( (char*)line.c_str(), line.size() );
However, if I disconnect the connection on the side of wxTerminal (i.e. COM2->NULL) than program hangs in this function.
It's obvious that I should add some function to test if my equipment is still there, but to do it I need to send data-packet to it and expect some answer. So I'm back to the Write().
"Just in case" I've also tried ctb::IOBase::Writev (char ∗ buf, size_t len, unsigned int timeout_in_ms) with timeout set to 100ms and I've still got program hanging in the same line. It's actually expected behavior as in this case timeout means only that the connection line is blocked till whole buffer is transferred or timeout is reached.
Connecting of wxTerminal to COM3 leads to un-freezing of debugger or stand-alone program. The Sun is shining, the birds are singing.
Can somebody give me a hint how to overcome my problem? I'd appreciate if comments would be restrained to wxWidgets-world - I really do not want to re-write whole program with other toolkit.
If you COM port library does not provide effective timeouts on write block, (presumably because of hardware flow-control), you could implement your own by threading off the write. You could use a couple of events/semaphores/condvar/whatever. One to signal to the thread that there is something in a buffer to send and another that you can wait on with a timeout that is signaled by the thread after it has sent the buffer. If the 'ack' wait times out, your COM port is stuck and you can pop up some 'Check cable' messageBox. I don't know what other calls your port lib supports, so I don't know how you could implement flushes/retries.

How to set a timeout for MySQL query using C API

I know there are lots of similar questions here, also there are lots of results, when I google it, but none of them answers my question. I read this, this, this and this but none of them works for me. I don't talk about any locks, I don't wanna do this using MySQL c++ connector, just the C API.
Also, what is very important here: I do this on LINUX. Why I mention this? Because in the documentation for mysql_options:
MYSQL_OPT_READ_TIMEOUT - ...This option works only for
TCP/IP connections and, prior to MySQL 5.0.25, only for Windows.
MYSQL_OPT_WRITE_TIMEOUT- ... This option works only for
TCP/IP connections and, prior to MySQL 5.0.25, only for Windows
So, is there any way to set a query timeout for versions, prior 5.0.25?
My MySQL version:
[root#xxx kiril]# mysql --version
mysql Ver 14.12 Distrib 5.0.22, for redhat-linux-gnu (i686) using readline 5.0
EDIT: At least, is there any way to cancel a query? I can start a timer as different thread, but when it expires.. can I cancel the query somehow?
Okay, I found a solution.. Thanks to Will and PRR( my co-worker ).
I cannot start a new thread on each query, as this is a real-time application, that is supposed to process 1000+ messages per second..(anyway, thanks to R.. for the idea).
Also, it was not possible to terminate the connection through the library, nor to cancel/kill the query, as the problem was in the DB server..
And here's a brute-force solution, but still much better that _EXIT( FAILURE ): Here's the related question: "How to force closing socket on Linux?" - so, I just closed the socket using a system call.
Important NOTE: (thanks Will) - It turned out, that our MySQL library wrapper has s "fail-safe" flag, so that on closed socket (or other critical error), it tries to "solve" the problem, so it reopens the socket, by itself, in my case. So, I just turned off this option and everything is fine now - the execute is terminated because of an exception - this is the "softest" way to do this.
This should be done through another thread, of course - a timer, for example.
EDIT: The timeouts are really working for versions after 5.0.25. But, at least on RHEL4 and RHEL5, the timeouts are tripled for some reason! For example, if some of the timeouts is set to 20sec, the real timeout is ~60sec..
Also, another important thing is, that these timeouts(as any other options) MUST be set after mysql_init and before mysql_connect or mysql_real_connect.
I suppose you could implement a timeout for the C function call (as described in this thread C++: How to implement a timeout for an arbitrary function call?), but you would need to think carefully about what kind of state you would leave the DB in - presumably these are just for reads of the database, not inserts/updates.
I have never tryed to do that, but i've been reading and i think that could means that MYSQL_OPT_WRITE_TIMEOUT and MYSQL_OPT_READ_TIMEOUT are only for windows prior MySQL version 5.0.25 but now sould be working for every TCP/IP connection. Take a look here
Regards
EDIT: I would try to update my mysql server to a newer version and try if it works.
If you don't mind using threads, you could start the query from a new thread and have the main thread perform a short pthread_cond_timedwait for the new thread to set a condition variable that it make the connection. Then you can let the thread linger around until the actual mysql call times out. Just make sure it's detached so its resources get freed when it finally does time out. This solution isn't pretty, but it should at least work.