C# 中如何判断一台主机是否在线?
try···chtch就免了。

解决方案 »

  1.   

    http://www.cnblogs.com/jhtchina/archive/2005/01/17/93007.html
      

  2.   

    判断一个主机是否在线,最自然而简单的办法是ping一下是否有响应:
    http://www.csharphelp.com/archives/archive6.html不过有些主机的防火墙是不允许IGMP请求的,比如XP SP2的默认设置,这样也没法
      

  3.   

    to  Sunmast(速马|AIR SUPPLY!)  
    http://www.csharphelp.com/archives/archive6.html
    这个上面的代码有问题,但你ping一个不存在的主机时它就停顿了。
    我测试了下,是nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
    这一句的问题,不知,你们还有没有什么好的办法
      

  4.   

    PingHost("ww.163.com");
    // 返回 Host not found
    PingHost("www.163.com");
    // 返回 Reply from 202.108.36.153:0 in 47MS :Bytes Received60没有问题的啊
    他的代码是基于.NET beta的,有几个地方语法不对,对应改过来就是了
      

  5.   

    /// <summary>
    /// This method takes the "hostname" of the server
    /// and then it ping's it and shows the response time
    /// </summary>
    public static void PingHost(string host)
    {
    //Declare the IPHostEntry 
    IPHostEntry serverHE, fromHE;
    int nBytes = 0;
    int dwStart = 0, dwStop = 0;
    //Initilize a Socket of the Type ICMP
    Socket socket = 
    new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); // Get the server endpoint
    try
    {
    serverHE = Dns.GetHostByName(host);
    }
    catch(Exception)
    {
    Console.WriteLine("Host not found"); // fail
    return ;
    } // Convert the server IP_EndPoint to an EndPoint
    IPEndPoint ipepServer = new IPEndPoint(serverHE.AddressList[0], 0);
    EndPoint epServer = (ipepServer); // Set the receiving endpoint to the client machine
    fromHE = Dns.GetHostByName(Dns.GetHostName());
    IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);        
    EndPoint EndPointFrom = (ipEndPointFrom); int PacketSize = 0;
    IcmpPacket packet = new IcmpPacket();
    // Construct the packet to send
    packet.Type = ICMP_ECHO; //8
    packet.SubCode = 0;
    packet.CheckSum = UInt16.Parse("0");
    packet.Identifier   = UInt16.Parse("45"); 
    packet.SequenceNumber  = UInt16.Parse("0"); 
    int PingData = 32; // sizeof(IcmpPacket) - 8;
    packet.Data = new Byte[PingData];
    //Initilize the Packet.Data
    for (int i = 0; i < PingData; i++)
    {
    packet.Data[i] = (byte)'#';
    } //Variable to hold the total Packet size
    PacketSize = PingData + 8;
    Byte [] icmp_pkt_buffer = new Byte[ PacketSize ]; 
    Int32 Index = 0;
    //Call a Method Serialize which counts
    //The total number of Bytes in the Packet
    Index = Serialize(  
    packet, 
    icmp_pkt_buffer, 
    PacketSize, 
    PingData );
    //Error in Packet Size
    if( Index == -1 )
    {
    Console.WriteLine("Error in Making Packet");
    return ;
    } // now get this critter into a UInt16 array //Get the Half size of the Packet
    Double double_length = Convert.ToDouble(Index);
    Double dtemp = Math.Ceiling( double_length / 2);
    int cksum_buffer_length = Convert.ToInt32(dtemp);
    //Create a Byte Array
    UInt16 [] cksum_buffer = new UInt16[cksum_buffer_length];
    //Code to initialize the Uint16 array 
    int icmp_header_buffer_index = 0;
    for( int i = 0; i < cksum_buffer_length; i++ ) 
    {
    cksum_buffer[i] = 
    BitConverter.ToUInt16(icmp_pkt_buffer,icmp_header_buffer_index);
    icmp_header_buffer_index += 2;
    }
    //Call a method which will return a checksum             
    UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length);
    //Save the checksum to the Packet
    packet.CheckSum  = u_cksum; 
        
    // Now that we have the checksum, serialize the packet again
    Byte [] sendbuf = new Byte[ PacketSize ]; 
    //again check the packet size
    Index = Serialize(  
    packet, 
    sendbuf, 
    PacketSize, 
    PingData );
    //if there is a error report it
    if( Index == -1 )
    {
    Console.WriteLine("Error in Making Packet");
    return ;
    }
             dwStart = System.Environment.TickCount; // Start timing
    //send the Pack over the socket
    if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR) 
    {
    Console.WriteLine("Socket Error cannot Send Packet");
    }
    // Initialize the buffers. The receive buffer is the size of the
    // ICMP header plus the IP header (20 bytes)
    Byte [] ReceiveBuffer = new Byte[256]; 
    nBytes = 0;
    //Receive the bytes
    bool recd =false ;
    int timeout=0 ; //loop for checking the time of the server responding 
    while(!recd)
    {
    nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
    if (nBytes == SOCKET_ERROR) 
    {
    Console.WriteLine("Host not Responding") ;
    recd=true ;
    break;
    }
    else if(nBytes>0)
    {
    dwStop = System.Environment.TickCount - dwStart; // stop timing
    Console.WriteLine("Reply from "+epServer.ToString()+" in "
    +dwStop+"MS :Bytes Received"+nBytes);
    recd=true;
    break;
    }
    timeout=System.Environment.TickCount - dwStart;
    if(timeout>1000)
    {
    Console.WriteLine("Time Out") ;
    recd=true;
    }
    }
        
    //close the socket
    socket.Close();     
    }
    /// <summary>
    ///  This method get the Packet and calculates the total size 
    ///  of the Pack by converting it to byte array
    /// </summary>
    public static Int32 Serialize(IcmpPacket packet, Byte[] Buffer,
    Int32 PacketSize, Int32 PingData )
    {
    Int32 cbReturn = 0;
    // serialize the struct into the array
    int Index=0; Byte [] b_type = new Byte[1];
    b_type[0] = (packet.Type); Byte [] b_code = new Byte[1];
    b_code[0] = (packet.SubCode); Byte [] b_cksum = BitConverter.GetBytes(packet.CheckSum);
    Byte [] b_id = BitConverter.GetBytes(packet.Identifier);
    Byte [] b_seq = BitConverter.GetBytes(packet.SequenceNumber);

    // Console.WriteLine("Serialize type ");
    Array.Copy( b_type, 0, Buffer, Index, b_type.Length );
    Index += b_type.Length;

    // Console.WriteLine("Serialize code ");
    Array.Copy( b_code, 0, Buffer, Index, b_code.Length );
    Index += b_code.Length; // Console.WriteLine("Serialize cksum ");
    Array.Copy( b_cksum, 0, Buffer, Index, b_cksum.Length );
    Index += b_cksum.Length; // Console.WriteLine("Serialize id ");
    Array.Copy( b_id, 0, Buffer, Index, b_id.Length );
    Index += b_id.Length; Array.Copy( b_seq, 0, Buffer, Index, b_seq.Length );
    Index += b_seq.Length; // copy the data         
    Array.Copy( packet.Data, 0, Buffer, Index, PingData );
    Index += PingData;
    if( Index != PacketSize/* sizeof(IcmpPacket)  */) 
    {
    cbReturn = -1;
    return cbReturn;
    } cbReturn = Index;
    return cbReturn;
    }
    /// <summary>
    /// This Method has the algorithm to make a checksum 
    /// </summary>
    public static UInt16 checksum( UInt16[] buffer, int size )
    {
    Int32 cksum = 0;
    int counter;
    counter = 0; while ( size > 0 ) 
    {
    // UInt16 val = buffer[counter]; cksum += Convert.ToInt32( buffer[counter] );
    counter += 1;
    size -= 1;
    } cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >> 16);
    return (UInt16)(~cksum);
    }
      

  6.   

    to  Sunmast(速马|AIR SUPPLY!)  
    你PingHost个不存在的ip试试.你ping 的那个是不存在的域名
    比如说:pingHost("222.222.222.222");
      

  7.   

    嗯,他这里用的都是同步的操作,也没有用多线程,确实会出问题
    最简单的可以改成多线程的,如果不想对他的代码做太大的改动:static string host = "128.0.0.1";static void Main(string[] argv)
    {
    TimeSpan timeOut = new TimeSpan(0,0,15); Thread pingThread = new Thread(new ThreadStart(PingHost));
    pingThread.IsBackground = true;
    pingThread.Priority = ThreadPriority.Highest;
    pingThread.Start();
    pingThread.Join(timeOut); Console.WriteLine("Done");
    Console.ReadLine();
    return;
    }然后把PingHost函数host参数去掉:
    static void PingHost()这样在15秒内如果一直没响应,则可以判定为主机不存在在socket编程,多线程/异步,必选其一
      

  8.   

    http://blog.csdn.net/zhzuo/archive/2004/03/21/22024.aspx
    SystemInformation.Network 属性
      

  9.   

    楼主还是先描述一下自己项目的情况,比如,可能你是在做一个chat程序?还是黑客程序?
    不同的用途可能会用到不同的方法