How to check if server is reachable in PCL project xamarin? - c#

I have been searching for solution to test or check the connectivity between my device and the server that contains my database.
Note: I want to implement the solution on my PCL project.

You can use James Montemagno's Connectivity Plugin for this.
You can either check if the device you are using is connected by calling;
bool isConnected = CrossConnectivity.Current.IsConnected;
Or, you can 'ping' a server to see if it can be reached. You can do that like this:
var isReachable = await CrossConnectivity.Current.IsReachable("google.com", 5000);
You can also provide an IP address. The second parameter is the timeout which defaults to 5 seconds. There is also the specific IsRemoteReachable method which also let's you specify a port number.
This library can be used in a PCL.
Note; for Android you will need the ACCESS_NETWORK_STATE and ACCESS_WIFI_STATE permissions, it should be added automatically when you install the NuGet package.

In the most cases it is completed with ICMP pings. You can ping the server every 1-5 secs depending on your appliation. But I suggest to use multicast address and ping that from the server because of performance and securtiy reasons (the last one needs firewall be configurated on server side too). You can determine connectivity lost if some of the replys (at least 3) doesn't reach the target host.

Related

'No connection could be made because the target machine actively refused it'

I am working on a 'Smart Device Project' using .Net Framework 3.5. I am trying to connect to some Java SOAP services on a remote server.
In order to do that, I added 'Web References' to my project.
When I try to call my web service I get a WebException 'Unable to connect to the remote server' with the inner exception being 'No connection could be made because the target machine actively refused it'.
I searched quite a lot on the Web and StackOverflow and found a lot of ASP configuration and 'Unavaliable port' answers, but as I have another application using the exact same Service successfully, I can't get why the new one isn't getting through (It did sometimes through my tests so I suppose my client implementation isn't that bad)
I tried to look if there was some connection issue on the port by using some TcpClient:
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
try
{
client.Connect("myServerName", 8087);
MessageBox.Show("Success");
} catch (Exception ex)
{
MessageBox.Show("Failure");
}
finally
{
client.Close();
}
This connection succeed.
Here is a sample on how I call my WebService:
WSServiceExtended srv = new WSServiceExtended();
srv.Proxy = new System.Net.WebProxy();
ServeurWSI wsi = new ServeurWSI();
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
wsr = srv.login(wsi);
The service is called 'Extended' because I overrided the auto-generated one in order to add Cookie managment since I am using the Compact Framework. Following the sample in this thread:
https://social.msdn.microsoft.com/Forums/en-US/34d88228-0b68-4fda-a8cd-58efe6b47958/no-cookies-sessionstate-in-compact-framework?forum=vssmartdevicesvbcs
EDIT:
I made some new tests with the Web references and got it to work.
When I add the Web Reference, I have to put some Url to the Web Service. When I set it with the actual hostname instead of the 'localhost' everything is fine.
But then, since I set it manually to the real address just before the call, it shouldn't matter
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
EDIT2:
I might have forgotten some specifics about my environnement.
The Web Services are exposed on my computer on some Tomcat Server.
The application I am working on is also developped on this computer (That's why I can add Web References by putting 'localhost' in the address)
The application is then deployed on a distant device (Windows CE) that will make calls the Web Services through WIFI (There, localhost wouldn't work then)
I tried calling the Web services from other computers successfully.
I'm beginning to think that there might be some differential between the called Url and the one that is set, otherwise, how would I have a difference in behaviour such as the one described in the first edit?
EDIT3:
Well..Seems like it's not a network issue but a .Net compact framework (usage?) issue...
The Url property of the Web Service implementation is simply ignored and the one in the Reference.cs is used in place.
If someone had some idea on how I could troubleshot this, I would really appreciate it.
That error means that you reached a server and the server said "no way". So you're either hitting the wrong server or the wrong port.
I find the telnet client is useful for testing stuff like this. From the command line, you can do:
telnet [servername] [port]
So something like:
telnet myServerName 8087
If it goes to a blank screen, then it connected successfully. If it does not connect, it'll tell you.
The telnet client is no longer installed by default in Windows 7+, so you'll have to install it. See here for instructions: https://technet.microsoft.com/en-ca/library/cc771275
If the connection does open, you could paste in an actual HTTP request to see what happens. A simple GET would look something like this:
GET /myServerApp/services/myService HTTP/1.1
Host: myServerName:8087
One reason for this error can be that the service binds to only a certain IP address. It could well be that the service only listens on the IP that is assigned to the host name, but not on the localhost IP (127.0.0.1).
For example:
If the host myServerName has the public IP 192.168.0.1, your service can choose to listen on all IPs assigned to the host (sometimes specifying 0.0.0.0), or it can specifically listen on 192.168.0.1 only. In that case you will not be able to connect through 127.0.0.1, because the service simply doesn't listen on that IP.
You can "use" this inverse of this feature to make a service accessible only to local clients, not on the public IP-Address, by listening on 127.0.0.1 only, but not on the public IP. This is sometimes used on Linux for example to make MySQL only accessible on the host itself.
I was starting to forget this post but I finally found the problem that was messing things up and it has nothing to do with programmation.
I was doing the calls while the device was connected to the computer via the 'Windows Mobile Device Center' allowing to access the device from Windows.
While connected, the host provided is ignored and all calls on the specified port are handled by the connected computer.
Disconnecting the device allows to communicate properly...

Mono Socket.Bind before connecting to use a specific interface

I'm attempting to connect to a remote server using a specific local interface. My logs tell me everything is working as intended, but checking with netstat, every connection is using the default interface.
I'm using the following code to bind a TcpClient to a specific Local Endpoint
Console.WriteLine("Binding to {0}", connectionArgs.LocalBindingInterface.ToString());
client = new TcpClient(connectionArgs.LocalBindingInterface);
Console.WriteLine("Bound to {0}", client.Client.LocalEndPoint.ToString());
Where connectionArgs.LocalBindingInterface is an IPEndPoint specified as such
IPEndPoint[] localEndPoints = new IPEndPoint[2];
localEndPoints[0] = new IPEndPoint(IPAddress.Parse("192.168.0.99"), 0);
localEndPoints[1] = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 0);
The IP addresses listed here are not the actual addresses.
When i check my logs, this is the info I get
Binding to 192.168.0.99:0
Bound to 192.168.0.99:59252
Binding to 192.168.0.100:0
Bound to 192.168.0.100:53527
But when i netstat -n -p --tcp -a I get
tcp 0 0 192.168.0.98:39948 remote_addr_here:443 ESTABLISHED 17857/mono
tcp 0 0 192.168.0.98:60009 remote_addr_here:443 ESTABLISHED 17857/mono
Clearly something's wrong here. None of the ports, nor the interfaces match. Netstat is run as sudo so I can't assume it's wrong. I also tried to manually create a socket, call it's bind method, and set the TcpClient's Client property to the manually bound socket, but I get the same result.
Is there something i'm doing wrong here? Is there a different way to force a Socket to use a specific Local EndPoint on mono?
I'm running this app as a non-root user, mono --version is Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-4ubuntu1.1), server's ubuntu version is Ubuntu 14.04.3 LTS
Edit 1:
Added an extra logging call after calling TcpClient.Connect()
Binding to 192.168.0.100:59000
Bound to 192.168.0.100:59000
After connect bound to 192.168.0.98:55484
Bottom line: you can't do this, not at the socket level.
The routing of outbound traffic is determined by the network routing configuration. You would have to create an explicit routing table entry for your destination to force a specific adapter to be used.
You can bind to a specific IP address, but this only causes inbound traffic to be filtered, i.e. you'll only receive traffic sent to that IP address.
There are related questions you may want to read as well:
How to stop behaviour: C++ Socket sendto changes interface — context is C++ and not constrained to Windows, but it has what is IMHO the most direct, most relevant notes on the topic.
Using a specific network interface for a socket in windows — fairly poor question and answer both, frankly. But it does contain some quotes and links that you might find useful anyway.
Arguably, this question might have been closed as a duplicate of one of those, or perhaps even another similar question. But those two don't really answer the question in an accurate, C#/.NET-specific way, and I didn't actually find any others that seemed any better.

What could explain this behavior in UDP multicast via WinRT?

Here is the scenario: I have 5 apps which all share a common DLL which contains P2P networking functionality that I wrote. One of these apps works perfectly every single time, but the others experience the following problem:
On a multicast broadcast our x86 based tablet can send and receive packets fine, but my x64 computer and ARM tablet can only send packets. The only difference is that they use different ports. I thought that must be it, and tried switching the other apps to use the same ports as the working app as a test, but that was a no-go. Here is the relevant portion of code that handles setting up the broadcasting system.
public async Task<bool> Startup() {
if (P2PNetwork.LocalUser == null || this._listenSocket != null)
return false;
ConnectionProfile connection = null;
//See note 1 below
bool gotConnection = TryGetValidNetworkConnection(out connection);
if(!gotConnection)
return false;
this._heartbeatTimer = ThreadPoolTimer.CreatePeriodicTimer(DoHeartbeat, TimeSpan.FromSeconds(10));
var socket = new DatagramSocket();
var stream = await socket.GetOutputStreamAsync(LANBroadcasting.MULTICAST_GROUP_ADDRESS, P2PNetwork.NetworkGroup.SendPort);
this._outStreamWriter = new DataWriter(stream);
this._listenSocket = new DatagramSocket();
this._listenSocket.MessageReceived += OnMessageReceived;
await this._listenSocket.BindServiceNameAsync(P2PNetwork.NetworkGroup.ReceivePort, connection.NetworkAdapter);
this._listenSocket.JoinMulticastGroup(LANBroadcasting.MULTICAST_GROUP_ADDRESS);
DoHeartbeat(HeartbeatFlags.Ping);
return true;
}
NOTE 1: These symptoms were happening before for all 5 applications. At that time I was using the BindServiceNameAsync without any arguments. After extensive research I found a page that suggested that that approach was not good, and that the Windows 8.1 method that takes a connection profile worked more reliably. I checked the profile multiple times and I get the wireless LAN profile, which is correct for both.
In this case (non-working) the tablet's send port is 50011 and its receive port is 50010. The multicast address is ff02::fb (I've tried IPv4 as well, no change) The PC in this case is the reverse of that. I confirmed that the packets are sending via Wireshark.
I also see this line of output via netstat -a on the PC (which is failing to receive)
UDP [::]:50011 *.*
Despite all this looking correct, my PC simply does not get the OnMessageReceived method called (except for the one app which mysteriously works). What should I be looking for that can cause this odd behavior? I tried changing the ports on the working application to see if it would fail but it didn't. I also tried running the app on a different tablet to see if it was just this PC, but I got the same results on the other tablet. Could the app be failing to join the multicast group? How would I know since the method returns void?
After a few days of banging my head against the wall, I finally got the answer. If you experience this problem, go to your Windows Firewall Settings and check what kind of network you are connected to. In my case, the Wi-Fi was a Guest / Public network. Apparently this means that it is considered "Internet" by the Windows Runtime and not "Private Network". In Package.appxmanifest I had the "Private Network (Client and Server)" options selected, but only "Internet (Client)" (which provides outbound access only) and not "Internet (Client and Server)" on all but the one application that was working for some reason.
On a side note: this doesn't explain why the one x86 tablet was still able to receive for all apps. I can only assume this is some kind of driver flaw.
This should really trigger some kind of warning message because this simple setting is way too easy to overlook.

WinCE 6.0, work with GPRS/WiFi

I'm working on a project, which should connect to servers through wifi/gprs. Project is an application for Windows CE 6.0 device, I'm writing in Visual Studio 2008 on C#.
I have two severs to work with. The first I have to connect via wifi, second - via gprs. So I need to know, how can I change the method of connecting between wifi and gprs?
I found and tried this way: I turn on both wifi and gprs on my device. So I work via wifi because it has a higher priority. When I need to work via gprs, I turn off wifi (SetDevicePower function). But when I turn wifi on, it doesn't connect back to my Preferred Network.
Also I heard about the way to change priority between gprs/wifi in OS priority table programmatically, but I didn't find any information about how to do this.
I hope you can help me.
I would use the route command from a shell.
lets assume
server1 ip: 123.123.123.1
server2 ip: 123.123.123.2
wifi ip : 192.168.1.101
gateway: 192.168.1.1
gprs ip : 10.1.2.3
gateway: 10.1.1.1
Now you can excute in a command prompt
route add 123.123.123.1 MASK 255.255.255.255 192.168.1.1
and
route add: 123.123.123.2 MASK 255.255.255.255 10.1.1.1
This should route all trafic to server 1 over wifi and to server 2 over gprs, without changing a single line of code in your app.
You can verify it worked with
tracert 123.123.123.1
tracert 123.123.123.2
However, you could use your app to periodically perform this task (I assume gprs ip could change from time to time) with Process.Start(...)
- delete route 1
- add route 1
- delete route 2
- add route 2
You even could specify the interface with the IF 2 switch (route list prints the interface id for your network cards).
Another interesting post to read is this one: http://ce4all.blogspot.com/2007/05/routing-ip-traffic-via-specified.html
The author uses the GetAdapterAddresses() and CreateIpForwardEntry() P/Invokes:
http://msdn.microsoft.com/en-us/library/ms927384.aspx
http://msdn.microsoft.com/en-us/library/ee495149%28v=winembedded.60%29.aspx

No response from sever on external IP in client-server IM app

I'm following a tutorial # http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html to try and gather the basics of networking. For those not wanting to hit the jump, it's a quick tut demonstrating how to program a simple client-server-model chat application.
When I try and run the code in the tut, it works fine as long as both the client and the server are on the same network, but the second I try and do it externally (getting a mate to run the client app, and running the server app my side), it all goes to pot. The fact that the code works when in the same network leads me to believe that it's not a coding issue, but an issue with the way my network is set up.
I'm trying to run the server on my IP address at port 21719, which I have opened, but still other people can't connect to my server, not able to get any form of response at all.
The code (from the tut) that is being used for the server to listen to connections is:
public void StartListening()
{
IPAddress ipaLocal = ipAddress; //ipAddress is parsed from txtIP
tlsClient = new TcpListener(ipaLocal, 21719);
tlsClient.Start();
ServRunning = true; //for the running loop
// Start the new tread that hosts the listener
thrListener = new Thread(KeepListening);
thrListener.Start();
}
Now, the tutorial does actually point out that
IPAddress ipaLocal = ipAddress;
Will cause issues on some configurations, and I'm beginning to fear that my configuration may be included in that.
So, does anyone have any solution for me?
Thanks,
Sam
What is the local IP address that you're using? (ipAddress) If it's 127.0.0.1, that's not correct (I don't know how it would work internally either, but Windows seems to use magic from time to time). Also, if you have multiple NICs in your local machine, maybe the port forwarding is only set up to forward to one of them, and you're using the IP of the other?
If that's not the problem, here are a few generic suggestions:
Grab a copy of netcat. It's a small network testing util whose only job is to form a simple TCP connection. That will allow you to eliminate your code as a variable in all this. If netcat can form a connection, then you know the problem is your code. If not, you've confirmed that it's your router.
You can use WireShark (or TShark) to look for ICMP packets. Capture ICMP packets on the remote machine. If you get "Destination Unreachable" from the router, you've again proved that it's your router.
As Spencer said you need to make sure Port Forwarding is setup on your router, to forward all packets that come in on port 21719 to your internal machine. As for exactly how to do that, it's hard to say without knowing what type of router.
Are you having people use your external (internet) IP address? (See yours here.)
Have you pinholed your router to forward all communications from port 21719 to your server?
Some tips:
What kind of operating system are you using? Please check the Scope and/or Profiles (under Advanced tab) of your firewall rule.
While your friend is trying to telnet to the port (connect to the im server) monitor the traffic using Wireshark or Network Monitor (Wireshark have problems with Vista and Win 7). If you don't see anything hitting your machine the problem is probably on the router side. Double check the settings - you said you set the forward rule (NAT) but did it also set the rule on firewall of your router?

Categories