Verify not only internet connection but if it is passing data - XAMARIN - c#

I'm having a problem with this verification of the internet connection. See I have this verification in my code:
if (CrossConnectivity.Current.IsConnected)
{
...
}
It works, but I think there is a situation that this do not cover, I have a shopping right next door to my office, I enter the shopping and the device just connects with the shopping WI-FI, but it's not passing data, because it need's to login in the session to get free WI-FI from the shopping.
So my question in resume is, is there a way, not only to verify if the device is conected to the internet, but if it is passing data through the connection?

I didn't try this solution but it might help you.
if (CrossConnectivity.Current.IsConnected)
{
if (ConnectGoogle())
{
return true;
}
else
{
//
}
}
ConnectGoogle method
public bool ConnectGoogle()
{
try
{
HttpURLConnection urlc = (HttpURLConnection)(new URL("http://www.google.com").OpenConnection());
urlc.SetRequestProperty("User-Agent", "Test");
urlc.SetRequestProperty("Connection", "close");
urlc.ConnectTimeout = 10000;
urlc.Connect();
return (urlc.ResponseCode == HttpStatus.Accepted);
}
catch (Exception ex)
{
//Log(ex.Message);
return false;
}
}

You could use System.Net.WebClient and test open/read an url. Also another way could be to ping a resource that is theoritically never offline. i.e. google.
Something like:
if (CrossConnectivity.Current.IsConnected)
{
try {
Ping ping = new Ping();
String host = "google.com";
byte[] buffer = new byte[32];
int timeout = 1000;
PingOptions pingOptions = new PingOptions();
PingReply reply = ping.Send(host, timeout, buffer, pingOptions);
if (reply.Status == IPStatus.Success){
// Your code here...
}
}
catch (Exception) {
return false;
}
}
Hope it helps.

Thanks everyone, I see all answers work in my situation, but I used this method from https://jamesmontemagno.github.io/ConnectivityPlugin/PingaHost.html, you could open it or just see it down here:
var verificaPassagemDados = await CrossConnectivity.Current.IsRemoteReachable("google.com");
Thanks #sme

Related

C# discover TCP client dissapeared

I have a TCPServer running like this :
await Task.Run(() =>
{
try
{
client = tcpClient;
bool Stop = false;
byte[] response = new byte[1024];
while (!ServerController.Token.IsCancellationRequested && !Stop)
{
Array.Clear(response, 0, response.Length);
var amount = tcpClient.Client.Receive(response);
string data = Encoding.UTF8.GetString(response);
if (amount == 0)
{
Stop = true;
ServerController.Token.ThrowIfCancellationRequested();
}
else
ProcesNewMessage(data);
}
if (ServerController.Token.IsCancellationRequested)
{
tcpClient.Close();
ServerController.Token.ThrowIfCancellationRequested();
}
}
catch (Exception exc)
{
tcpClient.Close();
Debug(exc.Message);
ServerController.Token.ThrowIfCancellationRequested();
}
}, ServerController.Token).ContinueWith(
(result) =>
{
clientDisconnected?.Invoke(this, EventArgs.Empty);
});
}
First of all the cancellation token does not work. I guess this is for another question.
My problem is detecting exiting sockets. In the case of a nice close by the socket at the other side I receive zero bytes (cached in the amount variable) but, the really troublesome scenario is unexpected disconnections from the client (power down, close the terminal, etc etc) How do I detect them ?
My clients are Arduino like chips so they are prone to die unexpectedly. How do I notice it?
PS: I'd like to avoid heartbeats since my devices run on batteries and sending over WiFi is my main lose of energy

Changing the IP address on an .NET 2.0 Remoting service breaks new clients from connecting

I have a C++ Windows service exposing a .Net Remoting interface for a local client to use and everything works great until the IP address changes.
Since I have to support .Net 2.0, switching to WCF isn't an option.
Any ideas on what I can do?
Here's how I set up the channel:
Hashtable^ dict = gcnew Hashtable();
dict["port"] = 9085;
dict["authenticationMode"] = "IdentifyCallers";
dict["impersonate"] = nullptr;
dict["secure"] = true;
dict["typeFilterLevel"] = "Full";
TcpServerChannel^ tcpChannel;
try
{
tcpChannel = gcnew TcpServerChannel( dict, nullptr);
}
catch (Exception^ e)
{
}
try
{
ChannelServices::RegisterChannel(tcpChannel, true);
}
catch (RemotingException^ RemoteException)
{
return FALSE;
}
catch (Exception^ e) { }
MyServiceProxy^ proxy = gcnew MyServiceProxy(m_pService);
RemotingServices::Marshal(proxy,"ServiceProxy");
Here's how I'm connecting to that service via C#
IDictionary dict = new Hashtable();
dict["port"] = 9085;
dict["name"] = "127.0.0.1";
dict["secure"] = true;
dict["tokenImpersonationLevel"] = "Impersonation";
dict["typeFilterLevel"] = "Full";
dict["connectionTimeout"] = 10000; // 10 seconds timeout
workChannel = new TcpClientChannel(dict, null);
try
{
ChannelServices.RegisterChannel(workChannel, true);
}
catch (System.Exception /*e*/)
{
}
string objectPath = "tcp://127.0.0.1:9085/ServiceProxy";
obj = (IMyService)Activator.GetObject(typeof(IMyService), objectPath);
I mean when the computers IP address changes. So here's the flow.
Start the service which sets up the channel, then close the laptop lid, go home, open it back up again, get assigned a new IP address, now when I try to start the client and it can't connect the the service.
After a good bit of research, I ran across the 'bindTo' parameter...and all I needed to do was to add the parameter to the TCPServerChannel dictionary.
dict["bindTo"]= "127.0.0.1";
If this didn't work, I was going to try to using the IPCServerChannel, but thankfully this one line was all I needed.
And to think, this one line has caused so much grief.
Thank you Alexei for helping.

How to detect if connection is unsuccessful using Watin?

I have a project about going to a website. If the website cannot because of several reasons, such as not being connected to the Internet, wrong proxy ip, etc, the browser will show a page with text "You're not connected to a network". In this situation, I want to auto refresh the browser. How will the program detect that website can't be loaded?
Take a look at my below code:
public void exam()
{
var ie = new IE();
ie.GoTo("http://search.yahoo.com");
ie.WaitForComplete(5);
if (ie.ContainsText("You're not connected to a network"))
{
ie.Close();// or ie.Refresh()
}
}
It doesn't work.
Try testing to see if you can Ping the address first ... try using this
public bool CanConnect()
{
var ping = new Ping();
var reply = ping.Send("search.yahoo.com");
return reply.Status == IPStatus.Success;
}
or if you want to pass the address as a parameter:
public bool CanConnect(string addressToTest)
{
var ping = new Ping();
var reply = ping.Send(addressToTest);
return reply.Status == IPStatus.Success;
}

How to use WMI commands to check if a system is connected to Internet? [duplicate]

This question already has answers here:
How do you determine if an Internet connection is available for your WinForms App?
(8 answers)
Closed 9 years ago.
In my winforms app i need to check if the system is connected to internet.
Currently I am using
try
{
Dns.GetHostEntry("www.something.com");
return true;
}
catch (Exception)
{
return false;
}
But this doesn't cut it for me. It takes more than two minutes to start the application if the system is not connected to internet(because of Timeout).
Was wondering if WMI command can be used instead?
I use This Class For Check Internet Connect
if User connect with Dsl Modem , below code Can't Sense Internet Connect
NetworkInterface.GetIsNetworkAvailable()
But This Class Can Solve This ,
class InternetConnectionChecker
{
private bool _connectingFlag = false;
private Thread _th;
#region Ping Google To Test Connect Or Disconnect
private string Ping()
{
try
{
const string remoteMachineNameOrIP = "173.194.78.104";
var ping = new Ping();
var reply = ping.Send(remoteMachineNameOrIP, 5);
var sb = new StringBuilder();
sb.Append(reply.Status.ToString());
return sb.ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
#endregion
#region Connecting Cheker Thread
private void ConCheck()
{
var status = Ping();
_connectingFlag = status == "Success" || status == "TimedOut";
}
public bool ConnectingCheker()
{
_th = new Thread(ConCheck);
_th.Start();
return _connectingFlag;
}
#endregion
}
For Use //Dont Forget Create Global Instance InternetConnectionChecker
InternetConnectionChecker _connectionChecker = new InternetConnectionChecker();
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
btn1.Content = _connectionChecker.ConnectingCheker();
}
I don't know about WMI, but there are some .NET Framework classes that can help in the System.Net.NetworkInformation namespace. In particular, NetworkInterface.GetIsNetworkAvailable() can tell you if a network connection (not necessarily with internet) is available. In the same namespace, the Ping class has several methods for send ping requests that are asynchronous and/or have timeout parameters.
I used wininet.dll instead to solve my problem and it works like a charm.
Please reference this link for its usage.
Thanks guys for your time.

Check if a port is open

I can't seem to find anything that tells me if a port in my router is open or not.
Is this even possible?
The code I have right now doesn't really seem to work...
private void ScanPort()
{
string hostname = "localhost";
int portno = 9081;
IPAddress ipa = (IPAddress) Dns.GetHostAddresses(hostname)[0];
try
{
System.Net.Sockets.Socket sock =
new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp);
sock.Connect(ipa, portno);
if (sock.Connected == true) // Port is in use and connection is successful
MessageBox.Show("Port is Closed");
sock.Close();
}
catch (System.Net.Sockets.SocketException ex)
{
if (ex.ErrorCode == 10061) // Port is unused and could not establish connection
MessageBox.Show("Port is Open!");
else
MessageBox.Show(ex.Message);
}
}
Try this:
using(TcpClient tcpClient = new TcpClient())
{
try {
tcpClient.Connect("127.0.0.1", 9081);
Console.WriteLine("Port open");
} catch (Exception) {
Console.WriteLine("Port closed");
}
}
You should probably change 127.0.0.1 to something like 192.168.0.1 or whatever your router's IP address is.
A better solution where you can even specify a timeout:
using System;
using System.Net.Sockets;
// ...
bool IsPortOpen(string host, int port, TimeSpan timeout)
{
try
{
using(var client = new TcpClient())
{
var result = client.BeginConnect(host, port, null, null);
var success = result.AsyncWaitHandle.WaitOne(timeout);
client.EndConnect(result);
return success;
}
}
catch
{
return false;
}
}
And, in F#:
open System
open System.Net.Sockets
let isPortOpen (host: string) (port: int) (timeout: TimeSpan): bool =
try
use client = new TcpClient()
let result = client.BeginConnect(host, port, null, null)
let success = result.AsyncWaitHandle.WaitOne timeout
client.EndConnect result
success
with
| _ -> false
let available = isPortOpen "stackoverflow.com" 80 (TimeSpan.FromSeconds 10.)
printf "Is stackoverflow available? %b" available
There is no way to know if the port is forwarded in your router, except if there is a program listening on that port.
As you may see in the Clinton answer, the .Net class being used is TcpClient and that is because you are using a TCP socket to connect to. That is the way operating systems make connections: using a socket. However, a router just forwards the packets (layer 3 of the OSI Model) in or out. In your case, what your router is doing is called: NAT. It is one public IP shared by a one or more private IPs. That´s why you are making a port forwarding.
There may be a lot of routers in the path of the packets, and you will never know what had happened.
Let´s imagine you are sending a letter in the traditional way. Perhaps you can write in the letter that the receiver must answer, in order to check he/she is there (you and the receiver are the sockets). If you receive an answer you will be sure he/she is there, but if you don´t receive anything you don´t know if the mailman (in your case the router) forgot to deliver the letter, or the receiver hadn´t answered. You would also never know if the mailman has asked a friend to deliver that letter. Moreover, the mailman won´t open the letter in order to know he/she may answer because you are waiting for a reply. All you may do is wait some time to receive the answer. If you don´t receive anything in that period you will assume that the receiver isn´t where you sent the letter. That is a "timeout".
I saw an answer mentioning the nmap software. It´s really a very good and complex soft, but I think it will work in the same way. If there is no app listening in that port, there is no way to know if it is open or not.
Please, let me know if I was clear.
If you're connecting to the loopback adapter — localhost or 127.0.0.1 (there's no place like 127.0.0.1!), you're unlikely to ever go out to the router. The OS is smart enough to recognize that it's a special address. Dunno if that holds true as well if you actually specify your machine's "real" IP address.
See also this question: What is the purpose of the Microsoft Loopback Adapter?
Also note that running traceroute localhost (tracert localhost in Windows) shows that the only network node involved is your own machine. The router is never involved.
Other than BeginConnect you can also use ConnectAsync (added in .NET Framework 4.5 I think?).
TcpClient client = null;
try {
client = new TcpClient();
var task = client.ConnectAsync(host, port);
if (task.Wait(timeout)) {//if fails within timeout, task.Wait still returns true.
if (client.Connected) {
// port reachable
}
else
// connection refused probably
}
else
// timed out
}
catch (Exception ex) {
// connection failed
}
finally {
client.Close();
}
Full project is here because paping refuses to run and I couldn't find another "ping host:port" tool to my likes.
A port forward on the router cannot be tested from inside the LAN, you need to connect from the WAN (internet) side to see if a port forward is working or not.
Several internet sites offer services to check if a port is open:
What's My IP Port Scanner
GRC | ShieldsUP!
If you want to check with your own code, then you need to make sure the TCP/IP connection is rerouted via an external proxy or setup a tunnel. This has nothing to do with your code, it's basic networking 101.
public static bool PortInUse(int port)
{
bool inUse = false;
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint [] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach(IPEndPoint endPoint in ipEndPoints)
{
if(endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
For me, I needed something blocking until the connection to the port is available or after a certain amount of retries. So, I figured out this code:
public bool IsPortOpen(string host, int port, int timeout, int retry)
{
var retryCount = 0;
while (retryCount < retry)
{
if (retryCount > 0)
Thread.Sleep(timeout);
try
{
using (var client = new TcpClient())
{
var result = client.BeginConnect(host, port, null, null);
var success = result.AsyncWaitHandle.WaitOne(timeout);
if (success)
return true;
client.EndConnect(result);
}
}
catch
{
// ignored
}
finally { retryCount++; }
}
return false;
}
Hope this helps!
also you can use ConnectAsync like
public async Task<bool> IsIPAndPortOpen(string hostOrIPAddress, int port, TimeSpan timeOut)
{
try
{
using (var client = new TcpClient())
{
var ct = new CancellationTokenSource(timeOut).Token;
await client.ConnectAsync(hostOrIPAddress, port, ct);
return true;
}
}
catch
{
return false;
}
}
public string GetAvailablePort()
{int startingPort=1000;
string portnumberinformation = string.Empty;
IPEndPoint[] endPoints;
List<int> portArray = new List<int>();
IPGlobalPr`enter code here`operties properties = IPGlobalProperties.GetIPGlobalProperties();`enter code here`
//getting active tcp listners
endPoints = properties.GetActiveTcpListeners();
portArray.AddRange(from n in endPoints
where n.Port >= startingPort
select n.Port);
portArray.Sort();
for (int i = 0; i < portArray.Count; i++)
{
if (check condition)
{
do somting
}
}
return portnumberinformation;
}
If it is Router the simplest way to check it through online services like
Port Checker
Port Forwarding Test
You can also try using telenet to chek wether port is accessible or not
telenet [ip-address] [port]

Categories