我正在尝试使用C#Ping ping我的一台服务器以查看它是否可用,但我收到一个奇怪的错误,我不确定导致它的原因
首次执行代码时,它会返回错误,但表示操作已成功完成
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]
每次在第一次执行代码后,都会返回不同的错误。
"An attempt was made to access a socket in a way forbidden by its access permissions."
System.Net.Sockets.SocketException (0x80004005)
我用来ping的代码如下所示,这几乎是从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;
}
我能够从我的机器上的终端ping服务器,但不能通过代码。为什么我收到此错误?
修改
我已在标准C#应用程序中测试了代码,它运行正常。这个问题必须与Unity有关。
Unity有自己的Ping类,但不能从主线程外部调用。下面的代码试图利用它,但它总是返回false和-1。
Ping应该在3秒内完成?我已经尝试将此时间增加到10秒但仍然返回false。地址肯定是可以ping的,因为我可以从终端ping它。
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);
}
}
由于这不起作用,我的下一个问题是Unity ping实际上是如何工作的?我的服务器处于安全环境中,只有特定的开放端口。如果它正在执行除标准ping之外的其他意外事件,则可能无法执行此操作。
编辑2
IEnumerator ping()
{
while (true)
{
WaitForSeconds f = new WaitForSeconds(0.05f);
Ping p = new Ping("ADDR");
while (!p.isDone)
{
yield return f;
}
PingFinished(p);
}
}
此代码似乎运行良好,但只能在主线程中运行。我需要一个能够从单独的任务或线程启动的解决方案。
答案 0 :(得分:0)
这似乎有效,但仅限于主线程。
IEnumerator ping()
{
while (true)
{
WaitForSeconds f = new WaitForSeconds(0.05f);
Ping p = new Ping("ADDR");
while (!p.isDone)
{
yield return f;
}
PingFinished(p);
}
}
答案 1 :(得分:0)
以下是关于如何在主线程上/下执行此操作的一般概念:
(警告:未经测试)
using System.Threading;
class Test : MonoBehaviour {
Ping result;
private object pingLock;
void Start() {
pingLock = new object();
new Thread(ThingRunningOffMainThread).Start();
StartCoroutine(DoPing());
}
IEnumerator DoPing()
{
WaitForSeconds f = new WaitForSeconds(0.05f);
Ping p = new Ping("ADDR");
while (!p.isDone)
{
yield return f;
}
Monitor.Enter(pingLock);
result = p;
Monitor.Pulse(pingLock);
Monitor.Exit(pingLock);
}
void ThingRunningOffMainThread() {
if (result == null) {
Monitor.Enter(pingLock);
while (result == null) {
Monitor.Wait(pingLock);
}
Monitor.Exit(pingLock);
}
PingFinished(pingLock);
}
}
要从后台线程调用主线程,请查看主线程调度程序,例如: