Recently I wrote a Discord-Bot in C++ with the sleepy-discord bot library.
Now, the problem here is that when I run the bot it shows me the following errors:
[2021-05-29 18:30:29] [info] Error getting remote endpoint: asio.system:9 (Bad file descriptor)
[2021-05-29 18:30:29] [error] handle_connect error: Timer Expired
[2021-05-29 18:30:29] [info] asio async_shutdown error: asio.ssl:336462100 (uninitialized)
Now, I searched far and wide what this could be triggered by but the answers always say like a socket wasn't opened and so on.
The thing is, it works on a lot of systems, but yesterday I was renting a VM (same system as my computer), and this seems to be the only one giving me that issue.
What could be the reason for this?
Edit: I was instructed to show a reproducible example, but I am not sure how I would write a minimal example that's why I link the bot in question:
https://github.com/ElandaOfficial/jucedoc
Update:
I tinkered a bit around in the library I am using and was able to increase the Websocketpp log level, thankfully I got one more line of information out of it:
[2021-05-29 23:49:08] [fail] WebSocket Connection Unknown - "" /?v=8 0 websocketpp.transport:9 Timer Expired
The error triggers when you so s.remote_endpoint on a socket that is not connected/no longer connected.
It would happen e.g. when you try to print the endpoint with the socket after an IO error. The usual way to work around that is to store a copy of the remote endpoint as soon as a connection is established, so you don't have to retrieve it when it's too late.
On the question why it's happening on the particular VM, you have to shift focus to the root cause. It might be that accept is failing (possibly due to limits like number of filedescriptors, available memory, etc.)
Related
I have written a small c++ application which is being automatically started after Windows boot on a couple of clients. This application will copy a file from a network share (same network share for all clients) to the local disk. When I reboot all clients at once, a bunch of them will get an error 1231 from the std::filesystem::copy function with following message:
"Network location cannot be reached"
If I reboot all clients with an interval of a couple of seconds between them, then there is no problem.
This makes me think that the copy function might be blocking the file during copying.
Is there some setting that I am missing that prevents this? Is this normal behaviour?
EDIT: I have been able to fix the network problem, I now however get an error 32 which states that "the process cannot access the file because it is being used by another process". Does the copy function lock the files that are currently being copied?
It sounds more like the network share has not been mounted yet. If all clients attempt to mount the same network share at the same time this may mean a lot of work for the server handing out the share. Consequently, some clients may time out and may have to repeat their request. Make sure the network share is actually mounted before you attempt to copy from it.
You are facing a problem due to an uninitialized network of your client workstations.
The error ERROR_NETWORK_UNREACHABLE - 1231 (0x4CF) indicates that the path provided is not reachable at an instance.
You can use two approaches:
1) Continue with while-loop until you get the success to check whether filepath exists. Handle the error situation with try-catch if any.
When you get the success go for download/copy.
2) Sleep for 60 sec to 180 sec before download/copy file in the current program.
I edited my question; there was indeed a problem with active directory where the client was not immediately given an IP address and thus not being able to access the share.
After some more testing, I now see that I am only able to perform a copy command on one of the clients using std::filesystem::copy, while the others show an error message 32, stating that "the process cannot access the file because it is being used by another process". If I use the xcopy command in a batch file instead on all devices simultaneously, I do not get any error...
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!
I'm trying to connect to a device on COM3 and the code runs until I call open("COM3"), which causes a stack overflow. Here's the relevant code:
asio::io_service io;
asio::basic_serial_port<asio::serial_port_service> scope(io);
//Open the connection and configure it
cout << "OPENING\n";
system::error_code error;
scope.open(PORT, error);
After opening the connection I configure it with the baud rate, etc.
It's hanging in win_iocp_serial_port_service.ipp, inside of SetCommState(handle, &dcb).
I also have some labview code to connect, send a command, and disconnect, which works. If I've run the labview code since starting up my computer, then my C++ program works (connects without hanging), but if I haven't yet run the labview code it gives me a stack overflow. This makes me think that I'm not starting up some driver or setting something persistent but I'm not sure what it would be.
If anyone's run into this issue or has any insight I appreciate the help!
Info from further testing: Connecting from non-labview serial connection clients seems to enable boost to connect as well. If I first connect via hyperterminal it works, and if I connect via command line (per this guide https://learn.sparkfun.com/tutorials/terminal-basics/command-line-windows-mac-linux) then I can subsequently connect via boost as well, which might be a workable solution, even if its dumb. Unfortunately I couldn't successfully send data with System.IO.Ports.SerialPort so the temporary solution is connect using System.IO.Ports.SerialPort, disconnect, then connect using boost asio now that it works. This works reasonably well but the code now only works on windows.
Since you can use your serial instrument from LabVIEW, your hypothesis that you're "not starting up some driver or setting something persistent" is probably correct.
You can see how LabVIEW and VISA are configuring the port and sending commands using a tool provided by NI called I/O Trace [1]. Once you have the working settings and commands in hand, you can match them with your calls to boost::asio and determine if you are over- or under-configuring the port.
In the I/O trace logs, you'll see VISA setting the baud, flow control, and the other traits before opening a session. The driver doesn't share much more than that, however, so if your program is using the same settings and sequence but still hanging, then scrutinize how you're programming to the asio interface [2].
References
[1] Performing a Good NI I/O Trace Capture for Debugging/Troubleshooting
http://digital.ni.com/public.nsf/allkb/282C5D41E2BA04F2862574BA007803B9
[2] Serial ports and C++
http://www.webalice.it/fede.tft/serial_port/serial_port.html
I am using gsoap for Symbian S60 3rd Edition FP2 in a Qt application. I am making several requests to a WS every 5 seconds. After 2 hours the application stops being able to connect to the WS and I get this Error 28: SOAP_TCP_ERROR from gsoap. If I stop the application and start it again it is able to connect to the WS again. Why is this happening?
I've put the gsoap WS call in a for loop and it stops connecting to the WS at the 892th time, every time I run it.
You can do several things as a prework:
enable DBGLOG at gsoap
use soap_faultdetail at client side.
I'm 99% sure that it will give you a tcp connection timeout error which means that connection handshake has just failed.
If it is so, it means that WS has not accepted the connection for some reason. The source of problems might lay somewhere between proxy/firewall/os/buggy ws/driver to name just few of them. Because of that, one can use reconnection attempt. I'm not familiar with symbian, but in the windows OS reconnection is performed behind the scenes:
see: https://technet.microsoft.com/en-us/library/cc938209.aspx
By default, reconnection attempt is made twice but this behaviour could be changed either by registry parameter, driver or winsock.
I think you have to write explicit connection-retry subroutine at your application level and force gSOAP to use it (see hooks section at gSOAP documentations) or just call soap_connect couple of times if it returns error.
NOTE: introduction of connection_timeout at gsoap level may be confusing.
If you will decide to put this one (if you do not already have this) in your code, perform some tests wether the reconnection attempt is really perfomed within this timeout or not.
What I'm just trying to say is that your application could set timeout to 30 minutes, but your OS will put SYN packet into the WS host just couple of times within let's say couple of first seconds. If the WS host will not respond with SYN-ACK for some reason, your gsoap's tcp_connect subroutine will fall into 30minutes waste-of-time-loop.
I have built a simple web service that simply uses HttpListener to receive and send requests. Occasionally, the service fails with "Specified network name is no longer available". It appears to be thrown when I write to the output buffer of the HttpListenerResponse.
Here is the error:
ListenerCallback() Error: The specified network name is no longer available at System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
and here is the guilty portion of the code. responseString is the data being sent back to the client:
buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
It doesn't seem to always be a huge buffer, two examples are 3,816 bytes and, 142,619 bytes, these errors were thrown about 30 seconds apart. I would not think that my single client application would be overloading HTTPlistener; the client does occasionally sent/receive data in bursts, with several exchanges happening one after another.
Mostly Google searches shows that this is a common IT problem where, when there are network problems, this error is shown -- most of the help is directed toward sysadmins diagnosing a problem with an app moreso than developers tracking down a bug. My app has been tested on different machines, networks, etc. and I don't think it's simply a network configuration problem.
What may be the cause of this problem?
I'm getting this too, when a ContentLength64 is specified and KeepAlive is false. It seems as though the client is inspecting the Content-Length header (which, by all possible accounts, is set correctly, since I get an exception with any other value) and then saying "Whelp I'm done KTHXBYE" and closing the connection a little bit before the underlying HttpListenerResponse stream was expecting it to. For now, I'm just catching the exception and moving on.
I've only gotten this particular exception once so far when using HttpListener.
It occurred when I resumed execution after my application had been standing on a breakpoint for a while.
Perhaps there is some sort of internal timeout involved? Your application sends data in bursts, which means it's probably completely inactive a lot of the time. Did the exception occur immediately after a period of inactivity?
Same problem here, but other threads suggest ignoring the Exception.
C# problem with HttpListener
May be that's not the right thing to do.
For me I find that whenever the client close the webpage before it load fully it gives me that exception. What I do is just add a try catch block and print something when the exception happen. In another word I just ignore the exception.
The problem occurs when you're trying to respond to an invalid request. Take a look at this. I found out that the only way to solve this problem is:
listener = new HttpListener();
listener.IgnoreWriteExceptions = true;
Just set IgnoreWriteExceptions to true after instantiating your listener and the errors are gone.
Update:
For a deeper explanation, Http protocol is based on TCP protocol which works with streams to which each peer writes data. TCP protocol is peer to peer and each peer can close the connection. When the client sends a request to your HttpListener there will be a TCP handshake, then the server will process the data and responds back to the client by writing into the connection's stream. If you try to write into a stream which is already closed by the remote peer the Exception with "Specified network name is no longer available" will occur.