Resource temporarily unavailable in Boost ASIO - c++

I get the error message "Resource temporarily unavailable" when I use the method receive_from(), it's a member of ip::udp::socket located here.
I pass to it: boost::asio::buffer, pointer to an endpoint object, flags (set to zero), and an error_code object.
I create the endpoint with just
new udp::endpoint()
There doesn't seem to be too much information available on this error message too. I've tried it on several machines and always get this error.

"Resource temporarily unavailable" is normally the text description for EAGAIN, indicating that the operation should be retried. In the case of UDP, it indicates that there isn't any data available at present, and you should try later.
It's generally worth looking at the man page for the underlying libc function; which is recvfrom in this case.

Related

WlanConnect Connection attempt fail

I am trying to connect to an unsecured network using the WlanConnect function. It is returning ERROR_SUCCESS, so far so good.
In my notification callback i receive WLAN_NOTIFICATION_ACM_CONNECTION_COMPLETE followed instantly by WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL.
Can someone give me a hint how i can find out what causes the connection to fail?
I'm assuming that you just forgot to mention the part where you called WlanRegisterNotification, since you say that your notification callback is actually receiving notifications.
As it turns out, you're in luckā€”the API provides you with just such a hint. In the documentation for the structure passed to you in the callback function, WLAN_NOTIFICATION_DATA, it describes what the WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL notification code means:
A connection attempt has failed.
A connection consists of one or more connection attempts. An application may receive zero or more wlan_notification_acm_connection_attempt_fail notifications between receiving the wlan_notification_acm_connection_start notification and the wlan_notification_acm_connection_complete notification.
The pData member points to a WLAN_CONNECTION_NOTIFICATION_DATA structure that identifies the network information for the connection attempt that failed.
And that structure has a wlanReasonCode member that contains a WLAN_REASON_CODE value that "indicates the reason for an operation failure." There are a bunch of error codes on that list. Check to see which one you are getting.
Also note that it is possible to receive a few WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL notifications before the connection ultimately connects successfully.

Boost Asio Error

I've tried to see if anyone else if having this problem, but I haven't found anything online yet. Does anything in this code looks like I'm invoking boost incorrectly?
This code works when I am logged into the machine that is starting the TCP server, but fails when no one is logged in. I stripped the code down to only look at the boost asio logic.
//create _acceptor, which will eventually listen for incomming connections, asynchronously
_acceptor = boost::shared_ptr<tcp::acceptor>(new tcp::acceptor(*_io_service));
_acceptor->open(tcp::endpoint(tcp::v4(), _port).protocol());
_acceptor->set_option(tcp::acceptor::reuse_address(false));
//omitted logic find a port that is open
_acceptor->bind(tcp::endpoint(tcp::v4(), _port));
//omitted error handling logic if open port not found
//Start listening for incoming connections asynchronously.
_acceptor->listen();
sslSocketPtr ssl_socket(sslSocketPtr(new ssl::stream<ip::tcp::socket>(*_io_service, _sslContext)));
_acceptor->async_accept(ssl_socket->lowest_layer(),
boost::bind(&TCPServer::handle_sslAccept, shared_from_this(), boost::asio::placeholders::error, ssl_socket));
When no one is logged into the machine, the ssl_socket constructor throws the exception: "static_mutex: Access is denied".
If I define BOOST_ASIO_ENABLE_OLD_SSL the code works correctly, but I think that may be contributing to another bug in my code. So I am trying to use the latest SSL logic from Boost.
Any help would be appreciated!
I'm going to assume from the symptoms that you run on Windows.
On windows, static_mutex is implemented as a named (interprocess) mutex and gets "opened" using CreateMutexW:
If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
As you can see you don't have the required permissions. However, you could still have this working if the mutex is always created by a privileged process. In that case you could modify the code that opens an existing named mutex with OpenMutex as the documentation hints.
It's likely easier to run the process under a user that has the required permissions thought

Error handling in overlapped socket IO

Can anyone please suggest a reliable way to handle system errors in case of using overlapped socket IO and IOCP?
MSDN description is cumbersome on this aspect. It says that for GetQueuedCompletionStatus return code FALSE there should be a subsequent GetLastError call to get error code on the failed operation. However, we know that for WSA-functions one should call WSAGetLastError instead (GetLastError returns 0 upon a socket error). So the first part of question is - how does it work in practice?
Another problem is handling errors if completion packets are extracted by GetQueuedCompletionStatusEx. MSDN describes only error handling for this call itself, saying nothing about obtaining error codes of individual failed operations.
Thanks in advance for all responses and comments.
After few hours of experimenting and studying MSDN with a magnifying glass I've found the following:
http://msdn.microsoft.com/en-us/library/ms684342%28v=VS.85%29.aspx (an article on OVERLAPPED structure, description of the Internal field):
The error code for the I/O request. When the request is issued, the system sets this member to STATUS_PENDING to indicate that the operation has not yet started. When the request is completed, the system sets this member to the error code for the completed request.
The Internal member was originally reserved for system use and its behavior may change.
The last phrase doesn't look good, but I guess it is what it is.

How do I get the SOAP response when there was an exception?

I made a call to a third party web service and get back an ESOAPHTTPException with a message in this format:
Cryptic message here - URL: http://webserviceurl - SOAPAction: performWithArgList
Now the support personnel for this web service has asked for the full SOAP response. Normally, I would attach an event handler to THTTPRIO.OnAfterExecute and simply store the content of the stream I receive as parameter.
But since Delphi raises the exception, that event handler doesn't execute. I understand that the exception may in fact mean that the service had failed in some catastrophic way, but there should still be some kind of response (not a timeout error).
Is there some other method I can use to trap the response before Delphi turns it into an exception?
For an ERemotableException-based exception you'd want to look at the OnAfterExecute event as it represents a fault sent back by the Service... but for ESOAPHTTPException (your case) you'll want to handle the OnWinInetError event ( http://docwiki.embarcadero.com/VCL/en/SOAPHTTPTrans.THTTPReqResp.OnWinInetError).
D2010 introduced a bug in the SOAP HTTP handling. The typical symptom is that it would miss HTTP failures (such as when the Server is busy). So maybe that's not the issue you're running into but without knowing the exact error code or message you're seeing, one cannot tell. You can find more details here: https://forums.embarcadero.com/message.jspa?messageID=304898&tstart=0
For example, if you're getting the error about 'Handle is in the wrong state', the issue mentioned above is the culprit. It means that the 'Send' failed but the runtime happily proceeded to read a response. You can find out more about that one from this thread: https://forums.embarcadero.com/message.jspa?messageID=307048.
So you should handle OnWinInetError and grab the error code (LastError param). That's probably key to understanding the failure.
Cheers,
Bruneau
Yes, you can use the RIO event to examine the response before it is deserialized.
OnAfterExecute
You'll get the response as a stream, which you can convert to a string. Then you can examine for bad things like exceptions, beign totally empty, or starting with '', which usually (in my case) indicates that the service isn't up.
I would open the source for SOAPHTTPTrans and put a break point inside THTTPReqResp.Check(), just inside the "if error". When you hit the breakpoint, you'll have more of an idea what's wrong. Look at the call stack to see how you got here. It's probably something going wrong with your reqest being created and sent. If it's during the send, then it's likely not ever going out on the network so you won't see it with WireShark, Fiddler, or SoapUI.
IMO, functions like Check() should have an extra parameter for CallerLocation, so that instead of calling this:
Check(not Assigned(Request), False);
you'd call this:
Check(not Assigned(Request), False, 'THTTPReqResp.SendGet');
and Check would append CallerLocation to the error message, and you'd know (a lot) more about what's going on.

"Specified network name is no longer available" in Httplistener

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.