[C#] Ping utility die vastloopt

Pagina: 1
Acties:

  • Raenius
  • Registratie: December 2003
  • Laatst online: 20-08-2021
Hoi,

Ik probeer een ping utility / class te importeren in mijn huidige programma, ik maak in een loop gebruik van de functie PingHost met een lijst van IP addressen die ik uit een database haal. Dit gaat goed wanneer de host online is maar wanneer deze offline is dan lukt het niet...het programma loopt dan vast en stopt pas als ik hem zelf afsluit... Originele artikel op: http://www.c-sharpcorner.com/network/ping.asp

Dit is het stukje code waar het om draait:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        try
            {
            serverHE = Dns.GetHostByName(host);
            }
        catch(SocketException e)
            {
            MessageBox.Show("SocketException caught!!!");
            return;
            }
        catch(ArgumentNullException e)
            {
            MessageBox.Show("ArgumentNullException caught!!!");
            return;
            }
        catch(Exception m)
            {
                MessageBox.Show("Host not found");
                return;
            }


Ik heb geprobeerde de errors af te vangen maar er wordt niks getoont. Het gaat dus mis na serverHE = Dns.GetHostByName(host); (wanneer een host down is). Kan het iets te maken hebben met een timeout of iets dergelijks?

Heeft iemand misschien suggesties?

ps. Mod: Rest van de code stond er eigenlijk bij ter verduidelijking maar ik snap het argument, ik hoop dat het zo iets duidelijker is.

http://www.catalogged.net/


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 26-05 23:39

mulder

ik spuug op het trottoir

Moet je niet op een timeout wachten van die specifieke host?

oogjes open, snaveltjes dicht


  • Raenius
  • Registratie: December 2003
  • Laatst online: 20-08-2021
Dan zou hij toch een exception moeten genereren?

Ook al wacht ik een kwartier...hij gaat niet meer verder :'(

http://www.catalogged.net/


Verwijderd

Raenius schreef op 22 maart 2004 @ 15:00:
Dan zou hij toch een exception moeten genereren?

Ook al wacht ik een kwartier...hij gaat niet meer verder :'(
je moet het zoeken in non-blocking calls, tipje levert bergen info op waar je verder mee kunt:
[google=blocking non-blocking calls]

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Verwijderd schreef op 22 maart 2004 @ 16:21:
[...]


je moet het zoeken in non-blocking calls, tipje levert bergen info op waar je verder mee kunt:
[google=blocking non-blocking calls]
Mjah leuk, maar ook al doe je dat, dan blijft je huidige thread niet hangen, maar een andere thread, en krijg je nog het resultaat van je call niet.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Raenius schreef op 22 maart 2004 @ 14:49:
ps. Mod: Rest van de code stond er eigenlijk bij ter verduidelijking maar ik snap het argument, ik hoop dat het zo iets duidelijker is.
d:)b 277 regels code is nooit verduidelijkend voor wat dan ook, hoe ervaren programmeur je ook bent ;)

Professionele website nodig?


  • Raenius
  • Registratie: December 2003
  • Laatst online: 20-08-2021
"If you are in blocking mode, and you make a method call which does not complete immediately, your application will block execution until the requested operation completes. If you want execution to continue even though the requested operation is not complete, change the Blocking property to false. The Blocking property has no effect on asynchronous methods. "


Wanneer ik socket.Blocking = false; zet en ik run de code dan geeft hij 1 keer een reply an alle volgende meldingen geeft hij aan dat hij een non-blocking call niet direct kon afsluiten en verwijst hij naar het volgende gedeelte:
code:
1
2
3
4
5
6
7
8
9
            while(!recd)
                {
                nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
                    if (nBytes == SOCKET_ERROR) 
                    {
                        MessageBox.Show("Host not Responding") ;
                        recd=true ;
                        break;
                    }


Opvallend is wel dat:

a) Het programma wel gewoon doorloopt en niet vast slaat.
b) Hij maar 1 keer een reply geeft, en voor de rest bij elke ping die error geft, wanneer ik het programma afsluit en opnieuw opstart geeft hij gelijk die error weer en geen reply meer

ps. Mod: Oke daar zit wel wat in ;-)

[ Voor 20% gewijzigd door Raenius op 22-03-2004 17:09 ]

http://www.catalogged.net/


  • Raenius
  • Registratie: December 2003
  • Laatst online: 20-08-2021
Het werkt nu gelukkig, wat probleempjes in de stack etc..voor de geinteresseerde is hier de werkende class:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
public class Ping
  {
    //Declare some Constant Variables
    const int SOCKET_ERROR = -1;
    const int ICMP_ECHO = 8;

    /// <summary>
    ///  This method takes the "hostname" of the server
    ///  and then it ping's it and shows the response time
    /// </summary>

    public void PingHost(string strPingHost, int iPingBytes, uint lngPingCount, uint lngPingTimeout)
    {
    //  string strHostToPing = "";
     // bool   bLoop = false;
     // bool   bAddressResolve = false;

      // iPingBytes = always 32 bytes!! (called in Hoofdscherm)

      const int     MAX_PACKET_SIZE = 65535;
      //Declare the IPHostEntry 
      IPHostEntry   PingTarget, PingSource;
      int           iBytesReceived = 0;
      int           dwStart = 0, dwStop = 0;
      uint          iLoop = 0;

      // Get the server endpoint
      try
      {
        PingTarget = Dns.GetHostByName(strPingHost);
      }
      catch(Exception)
      {
        MessageBox.Show("Unknown host {0}" , strPingHost); // fail
        return;
      }

      // Convert the server IP_EndPoint to an EndPoint
      IPEndPoint ipepServer = new IPEndPoint(PingTarget.AddressList[0],0);
      EndPoint epServer = (ipepServer);

      // Set the receiving endpoint to the client machine
      PingSource = Dns.GetHostByName(Dns.GetHostName());
      IPEndPoint ipEndPointFrom = new IPEndPoint(PingSource.AddressList[0],0);
      EndPoint   EndPointFrom = (ipEndPointFrom);

      int iPacketSize = 0;
      IcmpPacket PingPacket = new IcmpPacket();
      // Construct the packet to send
      PingPacket.Type = ICMP_ECHO; //8
      PingPacket.SubCode = 0;
      PingPacket.CheckSum = UInt16.Parse("0");
      PingPacket.Identifier   = UInt16.Parse("45");
      PingPacket.SequenceNumber  = UInt16.Parse("0");
      PingPacket.Data = new Byte[iPingBytes];
      //Initialize the Packet.Data
      for (int iCount = 0; iCount < iPingBytes; iCount++)
      {
        PingPacket.Data[iCount] = (byte)'#';
      }

      //Variable to hold the total Packet size
      iPacketSize = iPingBytes + 8;
      byte [] bytPktBuffer = new byte[iPacketSize];
      int iResult = 0;

      //Call a Method Serialize which counts
      //The total number of Bytes in the Packet
      iResult = Serialize(PingPacket, bytPktBuffer, iPacketSize, iPingBytes );

      //Error in Packet Size
      if( iResult == -1 )
      {
        MessageBox.Show("Error in Making Packet");
        return;
      }

      /* now get this critter into a ushort array */
      ushort [] cksum_buffer = new ushort[Convert.ToInt32( Math.Ceiling( Convert.ToDouble(iResult) / 2))];
      
      //Code to initialize the ushort array 
      int icmp_header_buffer_index = 0;
      for( int iCount = 0; iCount < cksum_buffer.Length; iCount++ ) 
      {
        cksum_buffer[iCount] = BitConverter.ToUInt16(bytPktBuffer, icmp_header_buffer_index);
        icmp_header_buffer_index += 2;
      }
      //Call a method which will return a checksum
      //Save the checksum to the Packet
      PingPacket.CheckSum = CheckSum(cksum_buffer);

      // Now that we have the checksum, serialize the packet again
      byte [] byteSendBuffer = new byte[ iPacketSize ];
      //again check the PingPacket size
      iResult = Serialize(PingPacket, byteSendBuffer, iPacketSize, iPingBytes );
      //if there is a error report it
      if( iResult == -1 )
      {
        MessageBox.Show("Error in Making Packet");
        return;
      }


      //Loop the ping for IntPingCount times (standard 4, to be lateron (for testing 1))
      long lngPacketsSent = 0, lngPacketsReceived = 0, lngTotalTransmitTime = 0;
      int  iMinTransmitTime = int.MaxValue, iMaxTransmitTime = int.MinValue;
      do
      {
        bool bReceived = false ;

        //Initialize a Socket of the Type ICMP
        Socket PingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
        //Set socket timeout, but this doesn't seem to work...
        PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, (int) lngPingTimeout);
        PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.SendTimeout, (int) lngPingTimeout);

        // Initialize the buffers. The receive buffer is the size of the
        // ICMP header plus the IP header (20 bytes)
        byte [] ReceiveBuffer = new byte [MAX_PACKET_SIZE];

        dwStart = System.Environment.TickCount; // Start timing
        //Gather stats

        lngPacketsSent ++;
        //send the Pack over the socket
        iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, SocketFlags.None , epServer);
        if ((iResult) == SOCKET_ERROR)
        {
          MessageBox.Show("Socket Error cannot Send Packet");
        }
        //Receive the bytes
        iBytesReceived = 0;
        //loop while waiting checking the time of the server responding 
        while(!bReceived)
        {
          try
          {
            iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
          }
          catch//(Exception e)
          {
            //LOG AS DOWN
            MessageBox.Show ("Host not responding to socket connection");
            bReceived = false;
            iLoop++;
            break;
          }
          if (iBytesReceived == SOCKET_ERROR)
          {
          // LOG SOCKET ERROR
          // LOG AS DOWN
            MessageBox.Show("SOCKET ERROR") ;
            bReceived = false;
            iLoop++;
            break;
          } 
          else if (iBytesReceived > 0)
          {
            bReceived = true;
            dwStop = System.Environment.TickCount - dwStart; // stop timing

            //Check for timeout
            if ( dwStop > lngPingTimeout)
            {
              // LOG AS DOWN

              MessageBox.Show ("Request timed out for "+ipepServer.Address.ToString());
              bReceived = false;
              System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
              iLoop++;
              break;
            }
            if (dwStop < 10)
            {
              // LOG AS UP!
              MessageBox.Show("Reply from "+ipepServer.Address.ToString()+" <10ms");//, ipepServer.Address.ToString(), iBytesReceived - 28);
              iLoop++;
            }
            else
            {
              // LOG AS UP!
              MessageBox.Show("Reply from "+ipepServer.Address.ToString()+" "+ dwStop+" Seconds");   //, ipepServer.Address.ToString(), iBytesReceived - 28, dwStop
              iLoop++;
            }
            break;
          }
        }
      }
        while (iLoop < lngPingCount);

      }

    /// <summary>
    ///  This method is used to get the Packet and calculates the total size
    ///  of the Pack by converting it to byte array
    /// </summary>
    public static int Serialize(IcmpPacket ThisPacket, byte[] Buffer, int PacketSize, int PingData )
    {
      int cbReturn = 0;
      // serialize the struct into the array
      int iIndex = 0;

      byte [] b_type = new byte[1];
      b_type[0] = ThisPacket.Type;

      byte [] b_code = new byte[1];
      b_code[0] = ThisPacket.SubCode;

      byte [] b_cksum = BitConverter.GetBytes(ThisPacket.CheckSum);
      byte [] b_id    = BitConverter.GetBytes(ThisPacket.Identifier);
      byte [] b_seq   = BitConverter.GetBytes(ThisPacket.SequenceNumber);

      // MessageBox.Show("Serialize type ");
      Array.Copy( b_type, 0, Buffer, iIndex, b_type.Length );
      iIndex += b_type.Length;

      // MessageBox.Show("Serialize code ");
      Array.Copy( b_code, 0, Buffer, iIndex, b_code.Length );
      iIndex += b_code.Length;

      // MessageBox.Show("Serialize cksum ");
      Array.Copy( b_cksum, 0, Buffer, iIndex, b_cksum.Length );
      iIndex += b_cksum.Length;

      // MessageBox.Show("Serialize id ");
      Array.Copy( b_id, 0, Buffer, iIndex, b_id.Length );
      iIndex += b_id.Length;

      Array.Copy( b_seq, 0, Buffer, iIndex, b_seq.Length );
      iIndex += b_seq.Length;

      // copy the data   
      Array.Copy( ThisPacket.Data, 0, Buffer, iIndex, PingData );
      iIndex += PingData;
      if( iIndex != PacketSize/* sizeof(IcmpPacket)  */) 
      {
        cbReturn = -1;
        return cbReturn;
      }

      cbReturn = iIndex;
      return cbReturn;
    }
    /// <summary>
    ///   Checksum - 
    ///     Algorithm to create a checksup for a buffer
    /// </summary>
    public static ushort CheckSum( ushort[] BufferToChecksum )
    {
      int iCheckSum = 0;

      for (uint iCount = 0; iCount < BufferToChecksum.Length; iCount++) 
      {
        iCheckSum += Convert.ToInt32( BufferToChecksum[iCount] );
      }

      iCheckSum = (iCheckSum >> 16) + (iCheckSum & 0xffff);
      iCheckSum += (iCheckSum >> 16);
      return (ushort)(~iCheckSum);
    }

    /// <summary>
    ///   Class that holds the Pack information
    /// </summary>
    public class IcmpPacket
    {
      public byte     Type;             // type of message
      public byte     SubCode;          // type of sub code
      public ushort   CheckSum;         // ones complement checksum of struct
      public ushort   Identifier;       // identifier
      public ushort   SequenceNumber;   // sequence number  
      public byte[]   Data;             // byte array of data
    } // class IcmpPacket  
  } // class ping


In ieder geval bedankt voor de hulp!

http://www.catalogged.net/

Pagina: 1