Error handling in overlapped socket IO - c++

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.

Related

how to resolve WSAEWOULDBLOCK error

I have an win7 application where i am sending data b\w 2 clients on a TCP connection. While testing i found out that i was getting WSAEWOULDBLOCK error frequently on my socket. To
resolve this error i put a while loop around it for ex.
do
{
size_t value = ::send(); /*with proper arguments*/
}while(GetLastError() == 10035);
So if i get error 10035 i will resend the data.
But now i see that this while loop runs sometimes infinitely and my application goes
into kind of deadlock state. I tried increasing the size of socket but still of no use.
If anybody has any idea how to resolve WSAEWOULDBLOCK error please let me know.
WSAEWOULDBLOCK is not really an error but simply tells you that your send buffers are full. This can happen if you saturate the network or if the other side simply doesn't acknowledge the received data. Take a look at the select() function, which allows you to wait until buffer space is available or a timeout occurs. There is also a way to bind a win32 event to a stream, which then allows its use with WaitForMultipleObjects in case you want to abort waiting early.
BTW: I initially wanted to object against your use of the term "deadlock", but this is also something that could be happening: If you wait to send some some response before receiving the next request, and the other side wants to send a next request instead of receiving your response, your applications are effectively deadlocked. Using select(), you can determine whether you can send data, receive data or that the connection has failed, which allows you to handle these case correctly and when they occur.
Note: I also assume that your code is not really a call to socket() but one to send/recv.

Suppress "Operation not permitted" error from socket

I have a small utility application that handles sockets, both TCP and UDP. Occasionally, I get the error "Operation not permitted" printed to stderr. My issues is, I handle the errors based on the return codes of the socket functions (and occasionally errno), and don't print anything. Thus, this message must be coming from one of the socket calls. I am not sure which one, as this message occurs so infrequently, it has been difficult to debug, but I think it is either coming from socket or sendto.
Is there a way to suppress all messages from being printed? I can handle the errors myself, I do not need the system doing it uncontrolled on my behalf.
Note, this is a Linux only application.
Thanks for the help.
Are you using any library on top of sockets API? The functions used to work with sockets are not supposed to print anything to stderr. I'd suggest using strace and/or ltrace to check where this message originates from in first place.

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.

Resource temporarily unavailable in Boost ASIO

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.

"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.