BinaryReader.Read does not throw IOException when the connection is lost - windows-phone-7

I use HttpWebResponse.BeginGetResponse() method to make a request to my server. The request has AllowReadStreamBuffering set to false so that the data will not be buffered. In the "Request Complete" notification I do the following (no error handling code included):
HttpWebResponse response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(result);
BinaryReader streamReader = new BinaryReader(response.GetResponseStream());
try
{
while ((readSize = streamReader.Read(buffer, 0, buffer.Length)) > 0)
{
...
}
}
catch (Exception)
{ // NEVER GET HERE!!
...
}
My problem is that I cannot detect connection errors during reading data from stream (during the while loop). The behavior is very strange: it finishes to read all data that the OS has in the cache and then returns 'readSize = 0' as in the case of "end of stream".
I was expecting streamReader.Read() to throw an IOException exception but it does not!
I tried to find a stream failed flag somewhere but it seems that there is none (Stream/BinaryReader/HttpWebResponse). Please help!
I tested this by using three scenarios and all had the same behavior:
Using the phone-to-PC USB connection
Phone connected to Internet using the PC USB connection
After few streamReader.Read() successful calls I disable the PC network card
Using WIFI connection
Phone connected to Internet using WIFI connection
After few streamReader.Read() successful calls I power off the WIFI router
Using WIFI connection
Phone connected to Internet using WIFI connection
After few streamReader.Read() successful calls I remove WAN cable (so it has no Internet access).
Thank you!
Mihai

If you are not getting an exception then one option is to check the number of bytes read against response.ContentLength

Related

System.Net.Http.HttpRequestException 'No route to host' on local network address?

I am trying to connect to one of mine IOT ESP32 based web server from Xamarin Android native based project with the following code:
client = new HttpClient();
Uri uri = new Uri( "http://192.168.0.5/sensors" );
client.Timeout = TimeSpan.FromSeconds(10);
HttpResponseMessage response = client.GetAsync( uri ).GetAwaiter().GetResult();
if( response.IsSuccessStatusCode )
{
string content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
Yet seems like the timout is ignored, and with or without it I am receiving
System.Net.Http.HttpRequestException: 'No route to host'
How to properly connect from Xamarin Android native app to an address inside my local network ?
What is causing this exception ?
The network is all fine, and the server is reachable from practically any other OS, including microcontrollers within it except Android.
Found workaround - redirecting port from the router to the server, and using external IP on this port seems like working.

How to fix "Guru Meditation Error" caused by http.GET();?

I want to send data on my web server from esp32. ESP32 can not get to website and reboot.
I used exaples from Arduino IDE.
I've tried to post(htt.POST("X")) something and got same error.
I marked code to find which line cause the problem.
Googled.
...
msg="192.168.4.22/parametr";
if(WiFi.status() == WL_CONNECTED){
if(client.connect(host,httpPort)){
http.begin(msg);
Serial.print("0");
Serial.print("[HTTP] GET...\n");
int httpCode = http.GET();
Serial.print("1");
...
I expect to get to website, but now esp32 reboots when achived http.GET() and never prints "1".
Error message: Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
The URL you are passing to http.begin() is incorrect. You need to include the http:// prefix (see here). Semantically, it makes more sense to name this variable url rather than msg.
Also ... Check the return value of http.begin() - in case it is still failing.
const char *url = "http://192.168.4.22/parametr";
// Check Wi-Fi connected, etc.
if (!http.begin(url)) {
Serial.println("HTTP client failed to connect ...");
}
else {
int httpCode = http.GET();
// etc.
}
The LoadProhibited fatal error indicates an attempt to read or write an invalid memory location. When the library failed to parse the URL you provided, some member of the HTTPClient object may have been left uninitialized.
Log output
To assist your debugging, try setting the 'Core debug level' in the Arduino IDE to 'Debug'.
Arduino IDE -> Tools -> Core Debug Level -> Debug
This will ensure that the ESP log messages - such as might be printed if initialization of the HTTP client fails - will be printed over the serial port.
For example, this is the log output I see if I fail to include the http:// protocol specifier in the URL (after changing the core debug level).

Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."

I have an application which works fine on Xcode6-Beta1 and Xcode6-Beta2 with both iOS7 and iOS8. But with Xcode6-Beta3, Beta4, Beta5 I'm facing network issues with iOS8 but everything works fine on iOS7. I get the error "The network connection was lost.". The error is as follows:
Error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo=0x7ba8e5b0 {NSErrorFailingURLStringKey=, _kCFStreamErrorCodeKey=57, NSErrorFailingURLKey=, NSLocalizedDescription=The network connection was lost., _kCFStreamErrorDomainKey=1, NSUnderlyingError=0x7a6957e0 "The network connection was lost."}
I use AFNetworking 2.x and the following code snippet to make the network call:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:policy];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:<example-url>
parameters:<parameteres>
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#“Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
I tried NSURLSession but still receive the same error.
Restarting the simulator fixed the issue for me.
We had this exact error and it turned out to be an issue with the underlying HTTP implementation of NSURLRequest:
As far as we can tell, when iOS 8/9/10/11 receive an HTTP response with a Keep-Alive header, it keeps this connection to re-use later (as it should), but it keeps it for more than the timeout parameter of the Keep-Alive header (it seems to always keep the connection alive for 30 seconds.)
Then when a second request is sent by the app less than 30 seconds later, it tries to re-use a connection that might have been dropped by the server (if more than the real Keep-Alive has elapsed).
Here are the solutions we have found so far:
Increase the timeout parameter of the server above 30 seconds. It looks like iOS is always behaving as if the server will keep the connection open for 30 seconds regardless of the value provided in the Keep-Alive header. (This can be done for Apache by setting the KeepAliveTimeout option.
You can simply disable the keep alive mechanism for iOS clients based on the User-Agent of your app (e.g. for Apache: BrowserMatch "iOS 8\." nokeepalive in the mod file setenvif.conf)
If you don't have access to the server, you can try sending your requests with a Connection: close header: this will tell the server to drop the connection immediately and to respond without any keep alive headers. BUT at the moment, NSURLSession seems to override the Connection header when the requests are sent (we didn't test this solution extensively as we can tweak the Apache configuration)
For mine, Resetting content and settings of Simulator works.
To reset the simulator follow the steps:
iOS Simulator -> Reset Content and Settings -> Press Reset (on the
warning which will come)
The iOS 8.0 simulator runtime has a bug whereby if your network configuration changes while the simulated device is booted, higher level APIs (eg: CFNetwork) in the simulated runtime will think that it has lost network connectivity. Currently, the advised workaround is to simply reboot the simulated device when your network configuration changes.
If you are impacted by this issue, please file additional duplicate radars at http://bugreport.apple.com to get it increased priority.
If you see this issue without having changed network configurations, then that is not a known bug, and you should definitely file a radar, indicating that the issue is not the known network-configuration-changed bug.
Also have a problem with beta 5 and AFNetworking 1.3 when running on iOS 8 simulator that results in a connection error:
Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
The same code works fine on iOS 7 and 7.1 simulators and my debugging proxy shows that the failure occurs before a connection is actually attempted (i.e. no requests logged).
I have tracked the failure to NSURLConnection and reported bug to Apple. See line 5 in attached image:
.
Changing to use https allows connection from iOS 8 simulators albeit with intermittent errors.
Problem is still present in Xcode 6.01 (gm).
I was experiencing this problem while using Alamofire. My mistake was that I was sending an empty dictionary [:] for the parameters on a GET request, rather than sending nil parameters.
Hope this helps!
Opening Charles resolved the issue for me, which seems very strange...
Charles is an HTTP proxy / HTTP monitor / Reverse Proxy that enables a developer to view all of the HTTP and SSL / HTTPS traffic between their machine and the Internet. This includes requests, responses and the HTTP headers (which contain the cookies and caching information).
what solved the problem for me was to restart simulator ,and reset content and settings.
See pjebs comment on Jan 5 on Github.
Method1 :
if (error.code == -1005)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_group_enter(downloadGroup);
dispatch_group_wait(downloadGroup, dispatch_time(DISPATCH_TIME_NOW, 5000000000)); // Wait 5 seconds before trying again.
dispatch_group_leave(downloadGroup);
dispatch_async(dispatch_get_main_queue(), ^{
//Main Queue stuff here
[self redoRequest]; //Redo the function that made the Request.
});
});
return;
}
Also some suggests to re-connect to the site,
i.e. Firing the POST request TWICE
Solution: Use a method to do connection to the site, return (id), if the network connection was lost, return to use the same method.
Method 2
-(id) connectionSitePost:(NSString *) postSender Url:(NSString *) URL {
// here set NSMutableURLRequest => Request
NSHTTPURLResponse *UrlResponse = nil;
NSData *ResponseData = [[NSData alloc] init];
ResponseData = [NSURLConnection sendSynchronousRequest:Request returningResponse:&UrlResponse error:&ErrorReturn];
if ([UrlResponse statusCode] != 200) {
if ([UrlResponse statusCode] == 0) {
/**** here re-use method ****/
return [self connectionSitePost: postSender Url: URL];
}
} else {
return ResponseData;
}
}
On 2017-01-25 Apple released a technical Q&A regarding this error:
Apple Technical Q&A QA1941
Handling “The network connection was lost” Errors
A: NSURLErrorNetworkConnectionLost is error -1005 in the NSURLErrorDomain error domain, and is displayed to users as “The network connection was lost”. This error means that the underlying TCP connection that’s carrying the HTTP request disconnected while the HTTP request was in progress (see below for more information about this). In some circumstances NSURLSession may retry such requests automatically (specifically, if the request is idempotent) but in other circumstances that’s not allowed by the HTTP standards.
https://developer.apple.com/library/archive/qa/qa1941/_index.html#//apple_ref/doc/uid/DTS40017602
I was getting this error as well, but on actual devices rather than the simulator. We noticed the error when accessing our heroku backend on HTTPS (gunicorn server), and doing POSTS with large bodys (anything over 64Kb). We use HTTP Basic Auth for authentication, and noticed the error was resolved by NOT using the didReceiveChallenge: delegate method on NSURLSession, but rather baking in the Authentication into the original request header via adding Authentiation: Basic <Base64Encoded UserName:Password>. This prevents the necessary 401 to trigger the didReceiveChallenge: delegate message, and the subsequent network connection lost.
I had the same problem. I don't know how AFNetworking implements https request, but the reason for me is the NSURLSession's cache problem.
After my application tracking back from safari and then post a http request, "http load failed 1005" error will appear.
If I stop using "[NSURLSession sharedSession]", but to use a configurable NSURLSession instance to call "dataTaskWithRequest:" method as follow, the problem is solved.
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
config.URLCache = nil;
self.session = [NSURLSession sessionWithConfiguration:config];
Just remember to set config.URLCache = nil;.
I have this issue also, running on an iOS 8 device.
It is detailed some more here and seems to be a case of iOS trying to use connections that have already timed out.
My issue isn't the same as the Keep-Alive problem explained in that link, however it seems to be the same end result.
I have corrected my problem by running a recursive block whenever I receive an error -1005 and this makes the connection eventually get through even though sometimes the recursion can loop for 100+ times before the connection works, however it only adds a mere second onto run times and I bet that is just the time it takes the debugger to print the NSLog's for me.
Here's how I run a recursive block with AFNetworking:
Add this code to your connection class file
// From Mike Ash's recursive block fixed-point-combinator strategy https://gist.github.com/1254684
dispatch_block_t recursiveBlockVehicle(void (^block)(dispatch_block_t recurse))
{
// assuming ARC, so no explicit copy
return ^{ block(recursiveBlockVehicle(block)); };
}
typedef void (^OneParameterBlock)(id parameter);
OneParameterBlock recursiveOneParameterBlockVehicle(void (^block)(OneParameterBlock recurse, id parameter))
{
return ^(id parameter){ block(recursiveOneParameterBlockVehicle(block), parameter); };
}
Then use it likes this:
+ (void)runOperationWithURLPath:(NSString *)urlPath
andStringDataToSend:(NSString *)stringData
withTimeOut:(NSString *)timeOut
completionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
OneParameterBlock run = recursiveOneParameterBlockVehicle(^(OneParameterBlock recurse, id parameter) {
// Put the request operation here that you want to keep trying
NSNumber *offset = parameter;
NSLog(#"--------------- Attempt number: %# ---------------", offset);
MyAFHTTPRequestOperation *operation =
[[MyAFHTTPRequestOperation alloc] initWithURLPath:urlPath
andStringDataToSend:stringData
withTimeOut:timeOut];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation, id responseObject) {
success(operation, responseObject);
}
failure:^(AFHTTPRequestOperation *operation2, NSError *error) {
if (error.code == -1005) {
if (offset.intValue >= numberOfRetryAttempts) {
// Tried too many times, so fail
NSLog(#"Error during connection: %#",error.description);
failure(operation2, error);
} else {
// Failed because of an iOS bug using timed out connections, so try again
recurse(#(offset.intValue+1));
}
} else {
NSLog(#"Error during connection: %#",error.description);
failure(operation2, error);
}
}];
[[NSOperationQueue mainQueue] addOperation:operation];
});
run(#0);
}
You'll see that I use a AFHTTPRequestOperation subclass but add your own request code. The important part is calling recurse(#offset.intValue+1)); to make the block be called again.
If the problem is occurring on a device, check if traffic is going through a proxy (Settings > Wi-Fi > (info) > HTTP Proxy). I had my device setup to use with Charles, but forgot about the proxy. Seems that without Charles actually running this error occurs.
I was connecting via a VPN. Disabling the VPN solved the problem.
I had same problem. Solution was simple, I've set HTTPBody, but haven't set HTTPMethod to POST. After fixing this, everything was fine.
I had to exit XCode, delete DerivedData folder contents (~/Library/Developer/Xcode/DerivedData or /Library/Developer/Xcode/DerivedData) and exit simulator to make this work.
If anyone is getting this error while uploading files to a backend server, make sure the receiving server has a maximum content size that is allowable for your media. In my case, NGINX required a higher client_max_body_size. NGINX would reject the request before the uploading was done so no error code came back.
I was hitting this error when passing an NSURLRequest to an NSURLSession without setting the request's HTTPMethod.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlComponents.URL];
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
Add the HTTPMethod, though, and the connection works fine
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlComponents.URL];
[request setHTTPMethod:#"PUT"];
I was facing the same issue,
I have enabled Network Link Conditioner for slow network testing for the app. That was creating this error some times,
When i have disabled it from Settings > Developer > Network Link Conditioner, it solved my problem.
Hope this help someone.
On top of all the answers i found one nice solution. Actually The issue related to network connection fail for iOS 12 onword is because there is a bug in the iOS 12.0 onword. And it Yet to resolved. I had gone through the git hub community for AFNetworking related issue when app came from background and tries to do network call and fails on connection establish. I spend 3 days on this and tries many things to get to the root cause for this and found nothing. Finally i got some light in the dark when i red this blog https://github.com/AFNetworking/AFNetworking/issues/4279
It is saying that there is a bug in the iOS 12. Basically you cannot expect a network call to ever complete if the app os not in foreground. And due to this bug the network calls get dropped and we get network fails in logs.
My best suggestion to you is provide some delay when your app are coming from background to foreground and there is network call. Make that network call in the dispatch async with some delay. You'll never get network call drop or connection loss.
Do not wait for Apple to let this issue solve for iOS 12 as its still yet to fix.
You may go with this workaround by providing some delay for your network request being its NSURLConnection, NSURLSession or AFNetworking or ALAMOFIRE. Cheers :)
I was having this issue for the following reason.
TLDR: Check if you are sending a GET request that should be sending the parameters on the url instead of on the NSURLRequest's HTTBody property.
==================================================
I had mounted a network abstraction on my app, and it was working pretty well for all my requests.
I added a new request to another web service (not my own) and it started throwing me this error.
I went to a playground and started from the ground up building a barebones request, and it worked. So I started moving closer to my abstraction until I found the cause.
My abstraction implementation had a bug:
I was sending a request that was supposed to send parameters encoded in the url and I was also filling the NSURLRequest's HTTBody property with the query parameters as well.
As soon as I removed the HTTPBody it worked.
Whenever got error -1005 then need to call API Again.
AFHTTPRequestOperationManager *manager =
[AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:policy];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:<example-url>
parameters:<parameteres>
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#“Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
if (error.code == -1005) {
// Call method again...
}
}];
You need to Add your code to call function again. MakeSure that you were call method once otherwise its call recursive loop.
I faced the same issue while calling using my company's server from iOS 12 app with a physical device. The problem was that the server hard disk was full. Freeing space in the server solved the problem.
I found the same error in another situation I think due to a timeout not parametrizable through the standard Networking API provided by Apple (URLSession.timeoutIntervalForRequest and URLSession.timeoutIntervalForResource). Even there.. made server answer faster solved the problem
This might be a problem of the parameter that you are passing to request body. I was also facing the same issue. But then I came across CMash's answer here https://stackoverflow.com/a/34181221/5867445 and I changed my parameter and it works.
Issue in a parameter that I was passing is about String Encoding.
Hope this helps.
My problem was on the server. I was using Python's BaseHTTPRequestHandler class and I wasn't sending a body in the response. My problem was solved when I put an empty body like the following.
def do_POST(self):
content_len = int(self.headers.get('Content-Length'))
post_body = self.rfile.read(content_len)
msg_string = post_body.decode("utf-8")
msg_json = json.loads(msg_string)
self.send_response(200)
self.end_headers() #this and the following lines were missing
self.wfile.write(b'')
I had the same issue, the problem was bug of Alomofire and NSUrlSession. When you returning back to app from safari or email you need to wait nearly 2 seconds to do you network response via Alamofire
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
Your network response
}
Got the issue for months, and finally discovered that when we disable DNSSEC on our api domain, everything was ok.

Actionscript 4: NetConnection.connect(...) does not fire a NetStatusEvent event

I downloaded the red5-recorder (http://www.red5-recorder.com/) , which fails to allow me to start recording. After debugging I found that the netconnection, needed to record to a media server, created does not fire a NetStatusEvent event, so essentially it fails silently. I have implemented the connection with the following minimal working example:
trace("make net connection");
nc = new NetConnection();
nc.client = { onBWDone: function():void{ trace("bandwidth check done.") } };
trace("add event listener");
nc.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent) {
trace("handle");
});
trace("connect!");
nc.connect("rtmp://localshost/oflaDemo/test/");
trace("connect done");
The output of this piece of code is:
make net connection
add event listener
connect!
connect done
The actionscript api states that the connect-call always fires such an event:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetConnection.html#includeExamplesSummary
Moreover, the netconnection is not 'connected' (a state of the NetConnection object) 10 seconds after the call. I also took a look at this: NetConnect fails silently in Flash when called from SilverLight But the fix suggested by the author, swapping rtmp and http in the connection uri, do not work. Also, I tested the uri and in fact the exact same code sniplet in a personal project, where it did work. I just can not seem to find why connecting to a media server fails silently in the red5-recorder project.
The awkward part is that if I pass some random string as a conenction uri, still nothing happens (no event, no exception, no crash). Also not setting nc.client becore nc.connect(), which caused exceptions in my experience, did not cause exceptions.
Any suggestions are welcome.
You are setting the address to localshost instead localhost.
nc.connect("rtmp://localshost/oflaDemo/test/");
Correct address:
nc.connect("rtmp://localhost/oflaDemo/test/");

Communication between C# running on Windows and C running on linux with protobuf

I have a server application running on Linux. This application was
developed using protobuf c and protobuf.rpc.c files for RPC communication.
I have a client application which was running on windows.It was developed in c# using protobuf-net.dll and ProtobufRemote.dll for RPC communication.Both application using the same proto file having same service methods.
I can able to create a proxy from C# client application with the below code.
using System.Configuration;
using System.Net.Sockets;
using ProtoBufRemote; // rpc reference
using StarCall; // proto file
#region Create client connection
Int32 port = Convert.ToInt32(ConfigurationManager.AppSettings["PORT"]);
TcpClient tcpClient = new TcpClient(ConfigurationManager.AppSettings["SERVERIP"].ToString(), port);
var controller = new RpcController();
var client = new RpcClient(controller);
var channel = new NetworkStreamRpcChannel(controller, tcpClient.GetStream());
channel.Start();
var service = client.GetProxy<Istarcall_services>();
if (service == null)
Console.WriteLine("error creating client..");
//now calls can be made, they will block until a result is received
Console.WriteLine("Client connected to Server....\n");
#endregion
But whenever I am trying to invoke a service method from C# client application as shown below, the application is hanging and not getting any response from Linux c server application.
try
{
Room_Config room = new Room_Config();
room.Room_Dial_Num = 1;
Room_Config roomRet = service.read_room(room); // service method
}
catch (Exception)
{
throw;
}
The application is hanging in the below code.
protected RpcMessage.Parameter EndAsyncCallHelper(string methodName, IAsyncResult asyncResult)
{
PendingCall pendingCall = (PendingCall)asyncResult;
pendingCall.AsyncWaitHandle.WaitOne(); // application hanging here
pendingCall.AsyncWaitHandle.Close();
if (pendingCall.IsFailed)
throw new InvalidRpcCallException(serviceName, methodName,
String.Format("Server failed to process call, returned error message: \"{0}\".",
pendingCall.ServerErrorMessage));
return pendingCall.Result;
}
According to above mentioned scenarios, I have the following queries.
Whether this protobuf remote c# dll can help to create a communicatgion from the linux c code. If not please help me how to create a communication channel with the linux c code.
Please provide if any alternative rpc dll for c# client application to communicate to linux protobuf c and protobuf rpc.c file.
Please tell me if my above approach is wrong and rectify with the suitable solution.
Please help me out. If not clear please send to mail mentioned below.
Have you implemented your server in Linux with ProtoBufRemote cpp available at https://code.google.com/p/protobuf-remote/ ??
If yes, then you must have replaced or modified SocketRpcChannel.cpp class as it is using WinSock2 that is not applicable on Linux.
Have you done so? If yes, please share modified SocketRpcChannel class that you have used in your server.
Thank you.

Resources