Check internet Connection on phone - c#

I wanted to check whether my phone can connect to Internet or not. I have seen several questions already. One of those is Question . It says to use NetworkInterface.GetIsNetworkAvailable() this and i tried it. I have disconnected my PC from internet and Also turned off the DataConnection of the emulator but NetworkInterface.GetIsNetworkAvailable() this always returning true. But simultaneouly i also check for NetworkInterfaceType.None and interestingly it is coming null.
Can anybody explain where i am missing info ?
Attempt : -
public static void CheckNetworkAvailability()
{
// this is coming true even when i disconnected my pc from internet.
// i also make the dataconnection off of the emulator
var fg = NetworkInterface.GetIsNetworkAvailable();
var ni = NetworkInterface.NetworkInterfaceType;
// this part is coming none
if (ni == NetworkInterfaceType.None)
IsConnected = false;
}
any help is appreciated :)

I am using following code to check if the device has access to internet with if it is connected to wifi or data connection..
public void UpdateNetworkInformation()
{
// Get current Internet Connection Profile.
ConnectionProfile internetConnectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
//air plan mode is on...
if (internetConnectionProfile == null)
{
Is_Connected = false;
return;
}
//if true, internet is accessible.
this.Is_InternetAvailable = internetConnectionProfile.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
// Check the connection details.
else if (internetConnectionProfile.NetworkAdapter.IanaInterfaceType != 71)// Connection is not a Wi-Fi connection.
{
Is_Roaming = internetConnectionProfile.GetConnectionCost().Roaming;
/// user is Low on Data package only send low data.
Is_LowOnData = internetConnectionProfile.GetConnectionCost().ApproachingDataLimit;
//User is over limit do not send data
Is_OverDataLimit = internetConnectionProfile.GetConnectionCost().OverDataLimit;
}
else //Connection is a Wi-Fi connection. Data restrictions are not necessary.
{
Is_Wifi_Connected = true;
}
}
Edit:
And for simple internet connection you can use below code.
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
Hope this helps!

The emulator always returns NetworkInterface.GetIsNetworkAvailable() as true, even if you emulate network conditions as having no network.
I faced this problem myself and the only truly way of testing this behaviour is to deploy the application to a physical device running Windows Phone and test it with the data turned off.

NetworkInterface.GetIsNetworkAvailable() checks the network connection and not the internet connection. If you are in any kind of network, then it will return true whether internet is present or not.
You can check the internet connection as following:
using System.Net
private bool IsOnline()
{
try
{
IPHostEntry iPHostEntry = Dns.GetHostEntry("www.wikipedia.com");
return true;
}
catch (SocketException ex)
{
return false;
}
}

Related

Why does IAsyncResult.AsyncWaitHandle.WaitOne return false when wifi has no internet connection and mobile data is turned on? (XAMARIN)

I'm trying to do a sync with my custom device via wifi connection. Everything works fine when my mobile data is turned off, but when it's turned on it won't work (because my custom device has no connection to the internet).
This is where the problem happens:
stateSuccess = true;
tcpclnt = new TcpClient();
IAsyncResult ar = tcpclnt.BeginConnect(ip, port, new AsyncCallback(connectCallback), stateSuccess);
int timeout = 3000;
stateSuccess = ar.AsyncWaitHandle.WaitOne(timeout, false);
when I have mobile data turned on stateSuccess = false, but when mobile data is turned off stateSuccess = true. I'm always connected over wifi to my custom device.
My connectCallback is:
private void connectCallback(IAsyncResult ar)
{
var stateSuccess = (Boolean)ar.AsyncState;
try
{
tcpclnt.EndConnect(ar);
}
catch (Exception exc)
{
//handle
}
try
{
if (tcpclnt != null && tcpclnt.Connected && stateSuccess)
return;
tcpclnt.Close();
}
catch (Exception exc)
{
if (tcpclnt != null)
tcpclnt.Close();
}
}
I think the problem is somewhere in it chosing the wrong network. How can I force it to use wifi network even thou the wifi has no internet connection?
The devices do not care nor discriminate the lower-level base-band radio scanning (we're talking about telephony here), that is left to the actual radio firmware to deal with.
If you dont want to use WIFI, turn it off. But if you want to force use WIFI, just turn your cellular data off
Edit: I just found a workaround to this that works ONLY for Android : https://stackoverflow.com/a/56590566/11104068

C# Detect Remote Assistance connection

I have an program in production environment where I like to have a window to open, when a remote assistance are started on the pc, so the person connecting to the pc have some more options. But i can't find anything if this is possible? If so any idea how to detect it?
This can be done but I find it tricky and I generally avoid this. See How to detect RDC from C#.net for more info.
To start RDP listens on port 3389 so something like this should work.
int port = 3389;
using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", false))
{
if (key != null)
{
object value = key.GetValue("PortNumber");
if (value != null) port = Convert.ToInt32(value);
}
}
But the port number can be configured so this isn't the best way.
Then there is Pinvoke and Cassia. with Cassia you could do something like:
public bool IsComputerUsedByTS()
{
var tsMgr = new TerminalServicesManager();
var localSvr = tsMgr.GetLocalServer();
var sessions = localSvr.GetSessions();
foreach(var session in sessions)
{
if(session.ConnectionState == ConnectionState.Active ||
session.ConnectionState == ConnectionState.Connected) //Add more states you want to check for as needed
{
return true;
}
}
return false;
}
And last but not least:
System.Windows.Forms.SystemInformation.TerminalServerSession
This uses a forms import but is a very simple solution. If you run your program in a remote desktop environment, this returns true.

Client Bluetooth connection with 32feet.NET fails all the time

I'm trying to get a Bluetooth socket connection up and running but for some reason my client will not connect.
More precisely I get an exception when I try to connect to the stream:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
All examples I found online didn't really solve my problem and I'm currently not really sure where the problem comes from.
The scanning and pairing works fine - I see that the Bluetooth device in question gets successfully paired.
I try to connect via first setting the Client and then call connect
Client Bluetooth name, address and pin are known:
public bool SetClient(String clientName, String btAddress, String pin)
{
bool retVal = false;
m_remoteBluetoothClient = new BluetoothDeviceInfo(BluetoothAddress.Parse(btAddress));
m_localBluetoothClient.SetPin(pin);
if (m_remoteBluetoothClient.Authenticated)
{
//m_localBluetoothClient.Authenticate = true;
retVal = true;
}
else
{
if (BluetoothSecurity.PairRequest(m_remoteBluetoothClient.DeviceAddress, pin))
{
retVal = true;
}
}
return retVal;
}
Then an async connect:
private void ClientConnectThread()
{
m_localBluetoothClient.BeginConnect(m_remoteBluetoothClient.DeviceAddress, BluetoothService.SerialPort, Connect, m_localBluetoothClient);
}
private void Connect(IAsyncResult result)
{
if (result.IsCompleted)
{
m_localBluetoothClient.EndConnect(result);
mBtStream = m_localBluetoothClient.GetStream();
}
}
The locals m_localBluetoothEndpoint and m_localBluetoothClient are created like this although the Endpoint is more or less new (before I used BluetoothCLient without parameter):
m_localBluetoothEndpoint = new BluetoothEndPoint(BluetoothRadio.PrimaryRadio.LocalAddress, BluetoothService.SerialPort);
m_localBluetoothClient = new BluetoothClient(m_localBluetoothEndpoint);
I also tried to work with a Listener in case the remote devices wants to connect but the callback gets never called:
public void SetupListener()
{
var listener = new BluetoothListener(BluetoothService.SerialPort);
listener.Start();
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallbackTwo, listener);
}
Can anyone tell me if there is anything wrong with my connection approach above and how I can figure out why I get the exception mentioned above?
The exception gets thrown here:
m_localBluetoothClient.EndConnect(result);
A thing I also don't understand is that the SupportedServices call to the remoteCLient returned 0 guids - so the device did not list any Bluetooth services.
m_remoteBluetoothClient.InstalledServices()
Thank you

Pair bluetooth devices to a computer with 32feet .NET Bluetooth library

If you want to know how to use 32feet.NET library to communicate with bluetooth devices, read the solution
I am currently trying to communicate via bluetooth between a computer and a self-built .NET Gadgeteer prototype.
The Gadgeteer prototype consists of the mainboard, a power supply and a bluetooth module. The module is in discoverable mode.
On the computer a custom bluetooth program based on 32feet .NET Bluetooth is running. The program detects all bluetooth devices in range and tries to pair with them. However, this is not done automatically at the moment, I have to enter a pairing code for the device.
How can I pair devices without entering the pairing code?
Devices are found, the problem is the pairing part. I experimented a lot, but didn't find a solution...
foreach (BluetoothDeviceInfo device in this.deviceList)
{
try
{
//BluetoothClient client = new BluetoothClient(this.CreateNewEndpoint(localAddress));
//BluetoothEndPoint ep = this.CreateNewEndpoint(device.DeviceAddress);
EventHandler<BluetoothWin32AuthenticationEventArgs> handler = new EventHandler<BluetoothWin32AuthenticationEventArgs>(HandleRequests);
BluetoothWin32Authentication auth = new BluetoothWin32Authentication(handler);
BluetoothSecurity.PairRequest(device.DeviceAddress, null);
}
}
This code block initiates the pairing and it works, but Windows is asking me to enter the pairing code for the device. I read about the BluetoothWin32Authentication to prevent this case but I don't get it right.
private void HandleRequests(object that, BluetoothWin32AuthenticationEventArgs e)
{
e.Confirm = true;
}
This is the code of the event handler (http://32feet.codeplex.com/wikipage?title=BluetoothWin32Authentication)
If you simply want to allow the pairing to go ahead when to SSP devices are connecting then handling the callback and setting e.Confirm=True will be enough -- but that is a little insecure...
I am confused -.- The goal is that the application and the gadgeteer module can send data in both directions without any user interference.
Is it true that I can't pair devices automatically without user interaction?
Is it true that if two device were already paired they can exchange data without user interaction?
I figured out how to solve my problems and my knowledge about Bluetooth connections is a bit bigger now. If someone else has problems with that, I provide my solution. The code examples represent the C# implementation of a bluetooth controller with the 32feet Bluetooth library.
Scanning
This means that devices in range are detected. My code:
// mac is mac address of local bluetooth device
BluetoothEndPoint localEndpoint = new BluetoothEndPoint(mac, BluetoothService.SerialPort);
// client is used to manage connections
BluetoothClient localClient = new BluetoothClient(localEndpoint);
// component is used to manage device discovery
BluetoothComponent localComponent = new BluetoothComponent(localClient);
// async methods, can be done synchronously too
localComponent.DiscoverDevicesAsync(255, true, true, true, true, null);
localComponent.DiscoverDevicesProgress += new EventHandler<DiscoverDevicesEventArgs>(component_DiscoverDevicesProgress);
localComponent.DiscoverDevicesComplete += new EventHandler<DiscoverDevicesEventArgs>(component_DiscoverDevicesComplete);
private void component_DiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
{
// log and save all found devices
for (int i = 0; i < e.Devices.Length; i++)
{
if (e.Devices[i].Remembered)
{
Print(e.Devices[i].DeviceName + " (" + e.Devices[i].DeviceAddress + "): Device is known");
}
else
{
Print(e.Devices[i].DeviceName + " (" + e.Devices[i].DeviceAddress + "): Device is unknown");
}
this.deviceList.Add(e.Devices[i]);
}
}
private void component_DiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e)
{
// log some stuff
}
Pairing
This means that devices get coupled with the local bluetooth device. This needs to be done once by entering a code of both sides. Can be done via code so that the user doesn't even notice that a device was added. My code for this purpose:
// get a list of all paired devices
BluetoothDeviceInfo[] paired = localClient.DiscoverDevices(255, false, true, false, false);
// check every discovered device if it is already paired
foreach (BluetoothDeviceInfo device in this.deviceList)
{
bool isPaired = false;
for (int i = 0; i < paired.Length; i++)
{
if (device.Equals(paired[i]))
{
isPaired = true;
break;
}
}
// if the device is not paired, pair it!
if (!isPaired)
{
// replace DEVICE_PIN here, synchronous method, but fast
isPaired = BluetoothSecurity.PairRequest(device.DeviceAddress, DEVICE_PIN);
if (isPaired)
{
// now it is paired
}
else
{
// pairing failed
}
}
}
Connecting
This means establishing a connection and exchanging of data. Again some code:
// check if device is paired
if (device.Authenticated)
{
// set pin of device to connect with
localClient.SetPin(DEVICE_PIN);
// async connection method
localClient.BeginConnect(device.DeviceAddress, BluetoothService.SerialPort, new AsyncCallback(Connect), device);
}
// callback
private void Connect(IAsyncResult result)
{
if (result.IsCompleted)
{
// client is connected now :)
}
}
If you keep the order scan, pair, connect, everything should work fine. To send or receive data, use the GetStream() method of the BluetoothClient. It provides a network stream that can be manipulated.
Receiving a connection
If you want another device to connect with your device you need to listen to incoming connection requests. This only works if the device have already been paired before. My code:
BluetoothListener l = new BluetoothListener(LOCAL_MAC, BluetoothService.SerialPort);
l.Start(10);
l.BeginAcceptBluetoothClient(new AsyncCallback(AcceptConnection), l);
void AcceptConnection(IAsyncResult result){
if (result.IsCompleted){
BluetoothClient remoteDevice = ((BluetoothListener)result.AsyncState).EndAcceptBluetoothClient(result);
}
}
Replace LOCAL_MAC with a valid BluetoothAddress (e.g. by using BluetoothAddress.Parse();). After the devices are connected they can exchange messages via the underlying stream. If the connection does not work there might be authentication issues, so try setting the local device pin in the listener (l.SetPin(LOCAL_MAC, MY_PASSWORD);

Listening for an Ethernet Cable Unplugging Event for a TCP Server Application

I have a C# TCP server application. I detect disconnections of TCP clients when they disconnect from server but how can I detect a cable unplug event? When I unplug the ethernet cable I can't detect the disconnection.
You might want to apply "pinging" functionality, that will fail if there is TCP connection lose. Use this code to add extension method to Socket:
using System.Net.Sockets;
namespace Server.Sockets {
public static class SocketExtensions {
public static bool IsConnected(this Socket socket) {
try {
return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
} catch(SocketException) {
return false;
}
}
}
}
Method will return false if there is no connection available. It should work to check if there is or no connection even if you had no SocketExceptions on Reveice / Send methods.
Bear in mind that if you had exception that had error message that is related to connection lose, then you don't need check for connection anymore.
This method is meant to be used when socket is looks like connected but might be not like in your case.
Usage:
if (!socket.IsConnected()) {
/* socket is disconnected */
}
Try the NetworkAvailabilityChanged event.
I found this method here. It checks the different states of the connection and signals a disconnect. But does not detect an unplugged cable. After a further search and trial and error this is how I solved it finally.
As the Socket parameter I use on the server side the client socket from the accepted connection and on the client side the client that connected to the server.
public bool IsConnected(Socket socket)
{
try
{
// this checks whether the cable is still connected
// and the partner pc is reachable
Ping p = new Ping();
if (p.Send(this.PartnerName).Status != IPStatus.Success)
{
// you could also raise an event here to inform the user
Debug.WriteLine("Cable disconnected!");
return false;
}
// if the program on the other side went down at this point
// the client or server will know after the failed ping
if (!socket.Connected)
{
return false;
}
// this part would check whether the socket is readable it reliably
// detected if the client or server on the other connection site went offline
// I used this part before I tried the Ping, now it becomes obsolete
// return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
}
catch (SocketException) { return false; }
}
This problem can also be resolved by setting the KeepAlive socket option like this:
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetKeepAliveValues(new SocketExtensions.KeepAliveValues
{
Enabled = true,
KeepAliveTimeMilliseconds = 9000,
KeepAliveIntervalMilliseconds = 1000
});
These options can be tweaked to set how often checks are done to ensure the connection is valid. The sending of the Tcp KeepAlive will trigger the socket itself to detect the disconnect of the network cable.

Categories