C# NetworkAvailabilitychangedEvent - c#

VS 2008
I am developing an application that has to detect whether a client has a network connection. i.e. LAN cable plugged in or wireless switched on. I have been using the code below.
I am using the NetworkAvailabilitychangedEvent to fire an event when their wireless is turned off or the cable has been pulled out. However, this only works if the user has only 3 connections present (LAN, Wireless, and loopbacks).
Microsoft: "The network is available when at least one network interface is marked "up" and is not a tunnel or loopback interface".
However, some client has more than 3 connections. One client had a bluetooth connection and someone else had some VMWare connections. On these client it failed to fire the event.
Is there anyway I can ignore all these connections I am not interested in listening out for, and just listen on the LAN and Wireless?
Many thanks for any advice,
private void Form1_Load(object sender, EventArgs e)
{
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(OnNetworkChangedEvent);
}
private void OnNetworkChangedEvent(object sender, NetworkAvailabilityEventArgs e)
{
bool available = e.IsAvailable;
NetworkInterface[] networkConnections = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in networkConnections)
{
if (ni.Name == "Local Area Connection")
{
if (ni.OperationalStatus == OperationalStatus.Down)
{
Console.WriteLine("LAN disconnected: " + ni.Description);
}
}
else if (ni.Name == "Wireless Network Connection")
{
if (ni.OperationalStatus == OperationalStatus.Down)
{
Console.WriteLine("Wireless disconnected: " + ni.Description);
}
}
}
}

Perhaps you need to implement some sort of polling agent that runs on a seperate thread and regularly tries to contact something listening on a remote server (or servers?).
When it fails (or perhaps when a preset number of connection attempts fail) then fire an event. Same when it goes from a fail-succeed state.
Your application would subscribe to these events and take action accordingly.
Of course this may not be suitable for your scenario..

Related

Problems enabling dtr in my serial communication program

I'm making a program which communicates with a serial port(RS232 mainly but in this instance I'm using a usb device). Right now I'm having a problem when enabling DTR.
private void CheckBox_DTR_CheckedChanged(object sender, EventArgs e)
{
if(COMport != null)
{
if (CheckBox_DTR.Checked)
{
COMport.DtrEnable = true;
}
else
{
COMport.DtrEnable = false;
}
}
}
In this part of my code I'm enabling DTR if checkbox gets checked. When I checked the pin voltage everything seems to be ok because voltage increases when I enable it. But there's the problem: when I enable DTR using other terminals the device throws out some info but when I do this with my program it doesn't send that info.
My program
Other Serial Terminal
As you can see other terminal has some additional info that device sends out upon enabling DTR. So I'm not completely sure what should I do to receive that info from the device(do I need some additional code or something)...
Generally, when using DTR you need to turn hardware handshaking on. I would try setting COMport.Handshake = Handshake.XOnXOff;.
According to MSDN here:
Data Terminal Ready (DTR) is typically enabled during XON/XOFF software handshaking and Request to Send/Clear to Send (RTS/CTS) hardware handshaking, and modem communications.

Determine if UDP host is reachable?

I have a metro app talking to a device over wifi using UDP. However, when I disconnect the device from the network or start the app with the device disconnected, nothing happens. ConnectAsync doesn't throw an exception, the app doesn't throw an exception, the app runs like nothing's wrong.
I can't ping the other end but If I give it a formatted string it will respond. The device is currently connected to a router which has internet access but I'm eventually planning to use a router without internet access. I've never done anything with UDP so I'm at a loss here.
Here is an implementation of a UDP listener/writer(taken from Pete Bright at 10rem.net)
class Network
{
private DatagramSocket _socket;
public bool IsConnected { get; set; }
public bool recieved;
public string ret;
public Network()
{
IsConnected = false;
_socket = new DatagramSocket();
_socket.MessageReceived += OnSocketMessageReceived;
}
public async void Connect(HostName remoteHostName, string remoteServiceNameOrPort)
{
try
{
await _socket.ConnectAsync(remoteHostName, remoteServiceNameOrPort);
}
catch (Exception e)
{
var msg = new MessageDialog(e.ToString());
msg.ShowAsync();
}
IsConnected = true;
}
private void OnSocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var reader = args.GetDataReader();
var count = reader.UnconsumedBufferLength;
var data = reader.ReadString(count);
ret = data.Trim();
recieved = true;
}
DataWriter _writer =null;
public async void SendMessage(string message)
{
if (String.IsNullOrEmpty(message)) return;
if (_writer == null)
{
var stream = _socket.OutputStream;
_writer = new DataWriter(stream);
}
_writer.WriteString(message);
await _writer.StoreAsync();
}
}
UDP Sockets are "connection-less", so the protocol does not know anything about whether or not the server and client are connected. To know if a a connection is still "active" you will have to implement your own connection detection.
I might recommend reading beej's guide to sockets. It's a good read and pretty funny:
http://beej.us/guide/bgnet/
As it was said, there is no concept like there is in tcp/ip with sync/ack, etc to communicate back and forth and ensure something is there.
Clients are neither connected nor disconnected, only listening or sending really.
So with that said you need to implement a receive timeout from the client.
There are some funny jokes with UDP, since you send data and just essentially fling it out into space. The order the packets are received can't matter either or you are stuck implementing your own scheme here as well.
What you'll need to do here is actually try to reach the device. If you care, then you can do this every X seconds.
As it is stated here: How to test a remote UDP Port
(keep with me, a better approach below this but wanted to provide multiple means)
You can use UdpClient, set a receive timeout on the underlying socket,
make a connection to that remote server/port, Send some small message
(byte[] !) and call Receive.
IF the port is closed you get an exception saying that the connection
was forcibly closed (SocketException with
ErrorCode 10054 = WSAECONNRESET)... which means the port is NOT open.
However- I think a better approach is to actually agree upon a protocol id or some specific data that the clients send every X seconds. If received, then update your 'client connected' table, otherwise consider them disconnected until the client sends a packet with a protocol id over.
A great series on this that you can probably easily adapt to c# is at:
http://gafferongames.com/networking-for-game-programmers/virtual-connection-over-udp/
I believe your code above can be refactored as well to only Send() to an address rather than connect, since there really is no true connect.
To help out people that stumble upon this:Apparently my google-fu is pretty weak. This shows how to set timeouts for TCP and UDP sockets. Default behavior is to never time out(which is consistent with what I saw).
Edit: It doesn't work. Even with a timeout of 500ms I'm still seeing the same behavior of "no exception thrown".

How can my C# Windows app be notified of changes in network status without polling?

I would like to be notified when the computer's network connection is established (has a valid IP address) and I would like to do this without polling. Is there a Windows API that can provide these notifications?
I would start with the System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged event.
Also WMI events might be possible, fired on changes to the set of Win32_NetworkAdapter or Win32_NetworkConnection instances.
http://www.codeproject.com/KB/IP/usenetworklist.aspx
"How to use the Windows NLM API to get notified of new network connectivity"
public MainForm()
{
// Set listener to Check if Network Address Changed
NetworkChange.NetworkAddressChanged += new
NetworkAddressChangedEventHandler(AddressChangedCallback);
}
static void AddressChangedCallback(object sender, EventArgs e)
{
MessageBox.Show("Network Changed");
}

Detecting Ethernet Port insertion/removal in my winforms application?

I would like to detect when a device is connected to an ethernet port of the machine that my application is running on. I know how to do this with a USB port but the problem is, the Port isn't USB!
If it was a USB device I would simply override WndProc and catch the message, if it is WM_DEVICECHANGE, then i'm on to a winner, I was wondering if it was as simple as this with any device that may be plugged into the port?
I don't want to know if there is anything happening, or if the device is working, just simply to find if there has been an insertion or removal.
I never used it myself, but I think that the NetworkChange.NetworkAvailabilityChanged event might fit your needs.
Update
A brief investigation indicates that NetworkChange.NetworkAddressChanged might work better:
public static void Main()
{
NetworkChange.NetworkAddressChanged += (s, e) =>
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (var item in nics)
{
Console.WriteLine("Network Interface: {0}, Status: {1}", item.Name, item.OperationalStatus.ToString());
}
};
string input = string.Empty;
while (input != "quit")
{
input = Console.ReadLine();
}
}
I'm not sure if that's exactly suited for your needs, but you could have a look at the System.Net.NetworkInformation.NetworkChange class, which has 2 events that you could use :
NetworkAddressChanged
NetworkAvailabilityChanged
In the event handler, you can check whether the network interface involved is an Ethernet port
The NetworkChange class provides you with a NetworkAvailabilityChanged event triggered when interfaces switch from down to up or vice versa. Possibly not as low level as you might be looking for but you aren't specific in your objective in tracking this event.

Block Ip Address

How to block one IP Address that is connected to the server, when the server is sending messages. My Sending message option program is shown below.
private void buttonSendMsg_Click(object sender, EventArgs e)
{
try
{
Object objData = richTextBoxSendMsg.Text;
byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
for (int i = 0; i < m_clientCount; i++)
{
if (m_workerSocket[i] != null)
{
if (m_workerSocket[i].Connected)
{
m_workerSocket[i].Send(byData);
}
}
}
}
It depends on the server. You can probably do this at the firewall level (and possibly the router level, if you have the right router). A rather simple way to block an IP is to just not accept connections from it wherever the connection would normally show up. In your own applications, this would mean checking the IP before opening it. Most servers allow you to block ips if you wish (e.g. IIS lets you create a blocklist (or an allow list) for each web site/application.
As Brian said, this should be a server issue and not an application issue. The server can block things at a much lower layer and is easier to configure.

Categories

Resources