Detect When Network Cable Unplugged

Detect When Network Cable Unplugged

Raymond Chen blogged about something similar recently. Here is the relevant documentation. I think the MIB_IPADDR_DISCONNECTED flag is what you are looking for.

How can I tell if a network cable has been unplugged?

You could use IsNetworkAlive(). Although technically it doesn't check link state, it's probably better since it can detect wireless and dialup connectivity as well. Here's an example:

using System.Runtime.InteropServices;
class Program
{
[DllImport("sensapi.dll")]
static extern bool IsNetworkAlive(out int flags);

static void Main(string[] args)
{
int flags;
bool connected = IsNetworkAlive(out flags);

}
}

The flags param returns whether the connection is to the internet or just a LAN. I'm not 100% sure how it knows, but I'd bet it just looks to see if there is a default gateway set.

Howto detect that a network cable has been unplugged in a TCP connection?

Unfortunately, there is no way to distinguish the cable being pulled out at the other end from any other reason for packet loss. Having said that, you can approximate loss of connectivity at the other end as "indefinite packet loss" occurring over a sufficiently long period of time (say T). TCP tracks packet loss, so the general approach for doing this would be:

  • Get the number of unacked bytes in the connection (say it's B)
  • send data, size = N
  • Set a timeout = T, when it fires, check the number of unacked bytes again. If it's B+N, then assume that the other side has lost connectivity. At this point, you could try ICMP echo to verify your assumption.

Getting TCP-specific information for a connection is not a standard interface on UNIX, and definitely not something portable to Windows. On Linux, there's a socket option called TCP_INFO, which you can call via getsockopt(). Google should give you some examples. I don't know if there's an equivalent option on Windows.

Another way to do this (i.e. approximate tracking of connectivity loss) is via RAW sockets. Open a RAW socket and filter it to receive only TCP traffic for your connection. Then rather than fetching information from TCP to determine if you are getting anything from the other end, simply wait to receive any packet from the other side. If you get something in the stipulated period, then it means the peer is still up.

Detect network cable unplugged errors with epoll

You have two options here:

  • Implement application-layer heartbeats. In other words, you write code that detects idle connections and periodically sends an application-layer message to essentially probe the connection and make sure that it's still open
  • You use TCP keepalive. This basically shifts the work of implementing and dealing with heartbeat messages down to the TCP layer. This seems like a good choice in your case.

To enable and configure TCP keepalive, you need to change the client_fd socket options with setsockopts(2). There are 3 parameters you need to check / change:

  • TCP_KEEPCNT - this is the number of outstanding, unanswered probes that are allowed at any given time. If more than TCP_KEEPCNT probes are sent with no reply within a given time interval, the connection is assumed to be dead.
  • TCP_KEEPIDLE - the amount of time the connection needs to be idle before probing packets start being sent.
  • TCP_KEEPINTVL - the time between individual probes.

So, you do something like this on client_fd:

int tcp_keepcnt = 3;
int tcp_keepidle = 30;
int tcp_keepintvl = 60;

setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt));
setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle));
setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl));

Broken connections are reported as readable by epoll(7), with the EPOLLHUP flag. Note that an order shutdown will be reported as readable without EPOLLHUP, but instead read(2) will return 0.

Keep in mind that detecting a dead connection is not immediate. It will take a while. For example, with the above parameters, it will take roughly 3 minutes.

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

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 */
}

Detect when ethernet cable is plugged

This links shows how to do it with Powershell, but one of the cases uses WMI.

http://www.powershellmagazine.com/2013/04/04/pstip-detecting-wi-fi-adapters/

And this links shows a interesting property that can help sometimes:

https://msdn.microsoft.com/en-us/library/aa394217(v=vs.85).aspx

GatewayCostMetric

Data type: uint16 array

Access type: Read-only Array

of integer cost metric values (ranging from 1 to 9999) to be used in
calculating the fastest, most reliable, or least resource-intensive
routes. This argument has a one-to-one correspondence with the
DefaultIPGateway property.



Related Topics



Leave a reply



Submit