I am trying to ping one of my servers using C# Ping to see whether it is available or not, but I am receiving a weird error and I'm not sure what's causing it
On first execution of the code, it returns an error but states that the operation was completed successfully
System.Net.Sockets.SocketException (0x80004005): The operation completed successfully.\r\n\r\n at System.Net.Sockets.Socket..ctor (System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) [0x00069]
Each time the code is executed after the first, it will return a different error.
"An attempt was made to access a socket in a way forbidden by its access permissions."
System.Net.Sockets.SocketException (0x80004005)
The code I am using to ping is as follows which is pretty much pulled straight from MSDN. https://msdn.microsoft.com/en-us/library/system.net.networkinformation.pingreply(v=vs.110).aspx
public static bool pingHost(string nameOrAddress)
{
bool pingable = false;
if (nameOrAddress == "127.0.0.1")
{
return true;
}
try
{
System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
PingOptions options = new PingOptions();
// Use the default Ttl value which is 128,
// but change the fragmentation behavior.
options.DontFragment = true;
// Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 3;//3 seconds?
PingReply reply = pingSender.Send(nameOrAddress, timeout);
if (reply.Status == IPStatus.Success)
{
pingable = true;
} else
{
pingable = false;
}
}
catch (PingException e)
{
Debug.Log("Error pinging: " + e.Message + " - " + e.StackTrace);
// Discard PingExceptions and return false;
}
return pingable;
}
I am able to ping the server from my terminal on my machine, but not through code. Why am I receiving this error?
EDIT
I have tested the code in a standard C# application and it works fine. This issue must be something related to Unity.
Unity has its own Ping class but can't be called from outside the main thread. The code below tries to utilise this, but it always returns false and -1 for the time.
Ping should definitely complete within 3 seconds? I have tried increasing this time to 10 seconds but still returns false. The address is definitely pingable as I can ping it from the terminal.
IEnumerator ping()
{
while (true)
{
UnityEngine.Ping pinger = new UnityEngine.Ping("ADDRESS");
yield return new WaitForSeconds(3.0f);
Debug.Log("Ping finished? " + pinger.isDone + " - " + pinger.time);
yield return new WaitForSeconds(2.0f);
}
}
As this doesn't work, my next question is how does the Unity ping actually work? My servers are in a secure environment with only specific open ports. If it is doing something unexpected other than the standard ping, it may not be able to.
EDIT 2
IEnumerator ping()
{
while (true)
{
WaitForSeconds f = new WaitForSeconds(0.05f);
Ping p = new Ping("ADDR");
while (!p.isDone)
{
yield return f;
}
PingFinished(p);
}
}
This code seems to work nicely, but only works from the main thread. I will need a solution that is able to be started from a separate task or thread.