Ping IPv6 Address with .Net does not work - c#

I am trying to make a simple ping to a host in my local network:
var ipString = "::ffff:192.168.178.20";
if (IPAddress.TryParse(ipString, out var ipaddr)){
var reply = new Ping().Send(ipaddr, 5000);
return reply.Status == IPStatus.Success ? "Good":"Bad"; //<- always returning "Bad"
}
The Ip Address gets parsed, but the ping runs into the 5s timeout. The ping works when I am using the windows console ('C:\ping ::ffff:192.168.178.20').
Does anyone has an idea what could be the reason for that behaviour?

Related

How to Ping for IPv4 only?

I know my router's IPv4 address. But when I Ping using TTL = 1 I don't get that IP. Rather, I get its IPv6 address. (I know of address.MapToIPv4() but that's only for IPv4s that were changed into IPv6s.)
So how do I ping for IPv4 only (like tracert's /4 switch)?
var reply = new Ping().Send("example.com", 10000, new byte[] { 1 }, new PingOptions(1, true));
Looking at the source code (Reference Source, GitHub), if the parameter passed to Send() is a name then Dns.GetHostAddresses() is used to resolve it and the first address returned is what's used. Thus, if that first address is an IPv6 address then that address is what will be pinged and there's no way to change that behavior.
Instead, you could call Dns.GetHostAddresses() yourself, filter the results to include or prefer IPv4 addresses, and pass that to Ping.Send():
IPAddress addressToPing = Dns.GetHostAddresses("example.com")
.First(address => address.AddressFamily == AddressFamily.InterNetwork);
using (Ping ping = new Ping())
{
PingReply reply = ping.Send(addressToPing, 10000, new byte[] { 1 }, new PingOptions(1, true));
// Do something with reply...
}

Weird C# Ping Exception

I'm experiencing a very annoying problem in my C# application. For some reason, this code is causing a System.Net.Sockets.SocketException with result:
"No such host is known." and 'connected' is always false.
bool connected;
try {
Ping pinger = new Ping();
PingReply reply = pinger.Send("http://www.google.com", 15000);
connected = reply != null && reply.Status == IPStatus.Success;
} catch {
}
The strange thing is that both pinging using the command prompt and http requests all result in success. Does anyone have any idea why this code is failing?
It's failing because it's taking the http:// as part of the host name, rather than the protocol.
Ping does not use the HTTP protocol, it uses ICMP. Changing the code to the following will fix your issue
Ping pinger = new Ping();
PingReply reply = pinger.Send("www.google.com", 15000);

Monitor continuosly if device is connected over IP

I have an electronic device which is connected to the computer over LAN. I have it's SDK to communicate with it.
Before communicating with the device it must be connected and registered with code provided in SDK. That's all fine.
My win application connects and registers the machine when the application starts up, but the problem is if the electronic device is SWITCHED OFF and then SWITCHED ON, the application must again connect and register the device.
So the question is how to continuously monitor if the device is connected over IP (something like PINGING it via C# code).
So one problem while constantly PINGing the device is that I must run it on separate thread, so that it doesn't affect my actual application. Another good solution would be if I get some piece code which fires event when the device is disconnected over IP.
Thanks for help.
Regards,
EDIT 1: Some piece of code which I use to connect using SDK
bool connected;
connected = axCZKEM1.Connect_Net("192.168.1.201", "4370");
bool registered;
registered = axCZKEM1.RegEvent(1, 65535);
EDIT 2: I am trying the method from answer by sa_ddam213, but I never get a ping failure. Also, it makes my PC run slow. What error am I making ?
while (true)
{
Ping ping = new Ping();
ping.PingCompleted += (sender, e) =>
{
if(e.Reply.Status != IPStatus.Success)
{
connected=false;
registered=false;
while(connected && registered)
{
connected = axCZKEM1.Connect_Net("192.168.1.201", 4370);
registered = axCZKEM1.RegEvent(1, 65535);
}
}
};
ping.Send("192.168.1.201", 3000);
}
You could Ping using c#,
PingReply reply = new Ping().Send("127.0.0.1");
if (reply.Status == IPStatus.Success)
{
// yay
}
Async method:
Ping ping = new Ping();
ping.PingCompleted += (sender, e) =>
{
if (e.Reply.Status == IPStatus.Success)
{
// yay
}
};
ping.SendAsync("127.0.0.1", 3000, null);

Unable to connect to the remote server when selecting IpEndPoint

I've got c# code running on a computer with multiple IP addresses, and I've got following code to select an IP address for a httpWebRequest:
class Interact
{
<data, cookies, etc>
HttpWebRequest CreateWebRequest(...)
{
.....
request.ServicePoint.BindIPEndPointDelegate = delegate(
ServicePoint servicePoint,
IPEndPoint remoteEndPoint,
int retryCount)
{
if (lastIpEndpoint!=null)
{
return lastIpEndpoint;
}
var candidates =
GetAddresses(remoteEndPoint.AddressFamily);
if (candidates==null||candidates.Count()==0)
{
throw new NotImplementedException();
}
return
lastIpEndpoint = new IPEndPoint(candidates[rnd.Next(candidates.Count())],0);
};
};
return request;
}
}
Here's the code of GetAddresses:
static IPAddress[] GetAddresses(AddressFamily af)
{
System.Net.IPHostEntry _IPHostEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
return (from i in _IPHostEntry.AddressList where i.AddressFamily == af select i).ToArray();
}
This code is supposed to select a random IP from avaliable IP list, and than stick to it.
Instead, every time I send request with it, I'm getting following exception:
Unable to connect to the remote server
How do I make this work?
It looks like you are setting the port number of the end point to zero in the line:
lastIpEndpoint = new IPEndPoint(candidates[rnd.Next(candidates.Count())],0);
Unless this gets changed later on, it is unlikely that you will be able to connect to an HTTP server on port 0. You may be able to use the port contained in the remoteEndPoint, or perhaps you can hard code the port number if it is well known (eg, 80 for HTTP server running on default port).
lastIpEndpoint = new IPEndPoint(candidates[rnd.Next(candidates.Count())], remoteEndPoint.Port);

Can't make TCP client code work without USB cable attached

I'm having a bit of trouble in getting a very simple TCP client working on my HTC Titan w/ Windows Phone 7.5.
When the USB cable is attached to the phone, the TCP client works like a charm, but as soon as the cable is unplugged, the client is unable to connect to a TCP server running on my development machine. The devices are on the same network and I'm using the explicit IP-address of my desktop machine to connect, so there's no name resolution going on afaik.
Here's the code I use. Most of it was taken from the Sockets samples on MSDN (can't seem to find the link now though).
private Socket _sock = null;
private ManualResetEvent _done = new ManualResetEvent(false);
private const int TIMEOUT = 5000;
//connect to server
public string Connect(string ip, int port) {
string result = string.Empty;
var host = new IPEndpoint(IPAddress.Parse(ip), port);
_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_sock.SetNetworkRequirement(NetworkSelectionCharacteristics.NonCellular);
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = host;
args.Completed += new EventHandler((s,e) => {
result = e.SocketError.ToString();
_done.Set();
});
_done.Reset();
_sock.ConnectAsync(args);
_done.WaitOne(TIMEOUT);
return result;
}
//send message
public string Send(string msg) {
string response = "Operation timeout";
if (_sock != null) {
var args= new SocketAsyncEventArgs();
args.RemoteEndPoint = _sock.RemoteEndPoint;
args.Completed += new EventHandler(s, e) => {
response = e.SocketError.ToString();
_done.Set();
});
var payload = Encoding.UTF8.GetBytes(data);
args.SetBuffer(payload, 0, payload.Length);
_done.Reset();
_sock.SendAsync(args);
_done.WaitOne(TIMEOUT);
}
return response;
}
//receive message
public string Receive() {
string response = "Operation timeout";
if (_sock != null) {
var args= new SocketAsyncEventArgs();
args.RemoteEndPoint = _sock.RemoteEndPoint;
args.SetBuffer(new Byte[MAX_BUFSIZE], 0, MAX_BUFSIZE);
args.Completed += new EventHandler((s,e) => {
if (e.SocketError == SocketError.Success) {
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else {
response = e.SocketError.ToString();
}
_done.Set();
});
_done.Reset();
_sock.ReceiveAsync(args);
_done.WaitOne(TIMEOUT);
}
return response;
}
The code is then simply used like:
Connect(...);
Send(...);
Receive(...);
//and then close the socket
As I said before, the code works like a charm when the device is attached to my development machine. When the cable is unplugged, the connection phase just times out (regardless of the timeout interval I should say).
Also, the manifest contains the ID_CAP_NETWORKING capability which as I understand it should give the app permission to access the network.
Any ideas?
EDIT:
I discovered that switching to UDP communication works like a charm. Which means that the problem is that for some reason, the phone is unable to set up a persistant TCP connection to my dev machine. This is getting stranger by the minute.
Do you have a wireless ap nearby on which your phone is connected? because when you plug it in the pc it uses the pc's network connection.
You should check the IP address that you have on both the phone (from your code) and on the PC (which it looks like you've already found using ipconfig in your command prompt).
These should be in the same IP address range, and so start with the same digits (for IPv4, probably something link 192.168.0.*).
If this all matches up check your wireless router hasn't enabled a security setting which means that it doesn't allow TCP traffic from your phone to your PC.
If this is a consumer router you manage this should be fairly simple to verify (and potentially fix). If not, you're probably stuck...

Categories