[Mono-bugs] [Bug 35371][Nor] Changed - Setting ReceiveTimeout causes exception
bugzilla-daemon@rocky.ximian.com
bugzilla-daemon@rocky.ximian.com
Sat, 31 May 2003 15:08:45 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by groith@tcrz.net.
http://bugzilla.ximian.com/show_bug.cgi?id=35371
--- shadow/35371 Sat May 31 07:18:32 2003
+++ shadow/35371.tmp.5025 Sat May 31 15:08:45 2003
@@ -112,6 +112,185 @@
{
Console.WriteLine ("Request timed out.");
}
+
+------- Additional Comments From groith@tcrz.net 2003-05-31 15:08 -------
+Here is a complete testcase, though it's a bit long:
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Ping
+{
+
+ class Ping
+ {
+ const int SOCKET_ERROR = -1;
+ const int ICMP_ECHO = 8;
+
+ public static void Main(string[] args)
+ {
+ PingHost("192.168.10.1", 32, 4, 1000);
+ }
+
+ public static void PingHost(string strPingHost, int iPingBytes,
+uint lngPingCount, uint lngPingTimeout)
+ {
+ const int MAX_PACKET_SIZE = 65535;
+ IPHostEntry PingTarget, PingSource;
+ int iBytesReceived = 0;
+ int dwStart = 0, dwStop = 0;
+ uint iLoop = 0;
+ bool bContinuous = false;
+
+ PingTarget = Dns.GetHostByName(strPingHost);
+
+ IPEndPoint ipepServer = new IPEndPoint(PingTarget.AddressList
+[0],0);
+ EndPoint epServer = (ipepServer);
+
+ PingSource = Dns.GetHostByName(Dns.GetHostName());
+ IPEndPoint ipEndPointFrom = new IPEndPoint
+(PingSource.AddressList[0],0);
+ EndPoint EndPointFrom = (ipEndPointFrom);
+
+ int iPacketSize = 0;
+ IcmpPacket PingPacket = new IcmpPacket();
+ 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];
+
+ for (int iCount = 0; iCount < iPingBytes; iCount++)
+ {
+ PingPacket.Data[iCount] = (byte)'#';
+ }
+
+ iPacketSize = iPingBytes + 8;
+ byte [] bytPktBuffer = new byte[iPacketSize];
+ int iResult = 0;
+
+ ushort [] cksum_buffer = new ushort[Convert.ToInt32(
+Math.Ceiling( Convert.ToDouble(iResult) / 2))];
+
+ 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;
+ }
+
+ byte [] byteSendBuffer = new byte[ iPacketSize ];
+
+ if (lngPingCount == 0) bContinuous = true;
+
+ long lngPacketsSent = 0, lngPacketsReceived = 0,
+lngTotalTransmitTime = 0;
+ int iMinTransmitTime = int.MaxValue, iMaxTransmitTime =
+int.MinValue;
+ do
+ {
+ bool bReceived = false ;
+
+ Socket PingSocket = new Socket(AddressFamily.InterNetwork,
+SocketType.Raw, ProtocolType.Icmp);
+
+ // Mono Bug 1:
+ // This should work without catching the exception
+
+ try {
+ PingSocket.SetSocketOption( SocketOptionLevel.Socket,
+SocketOptionName.ReceiveTimeout, (int) lngPingTimeout);
+ PingSocket.SetSocketOption( SocketOptionLevel.Socket,
+SocketOptionName.SendTimeout, (int) lngPingTimeout);
+ }
+ catch {}
+
+ byte [] ReceiveBuffer = new byte [MAX_PACKET_SIZE];
+
+ dwStart = System.Environment.TickCount; // Start timing
+ lngPacketsSent ++;
+ iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize,
+SocketFlags.None , epServer);
+ iBytesReceived = 0;
+ while(!bReceived)
+ {
+ try
+ {
+ // Mono Bug 2:
+ // On Linux This will just hang, instead of going on.
+
+ iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer,
+MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
+ }
+ catch //(Exception e)
+ {
+ Console.WriteLine ("Request timed out.");
+ bReceived = false;
+ break;
+ }
+ if (iBytesReceived == SOCKET_ERROR)
+ {
+ Console.WriteLine("Host not Responding") ;
+ bReceived = false;
+ break;
+
+ }
+ else if (iBytesReceived > 0)
+ {
+ bReceived = true;
+ dwStop = System.Environment.TickCount - dwStart; // stop
+timing
+
+ //Check for timeout
+ if ( dwStop > lngPingTimeout)
+ {
+ Console.WriteLine ("Request timed out.");
+ bReceived = false;
+ System.Threading.Thread.Sleep
+(System.TimeSpan.FromMilliseconds(1000));
+ break;
+ }
+ break;
+ }
+ }
+
+
+ iLoop++;
+
+ if (bReceived &
+ (bContinuous | (iLoop < lngPingCount)))
+ {
+ System.Threading.Thread.Sleep
+(System.TimeSpan.FromMilliseconds(1000));
+ }
+
+ PingSocket.Shutdown(SocketShutdown.Both);
+ PingSocket.Close();
+ } while (bContinuous | (iLoop < lngPingCount));
+
+ }
+
+
+ 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
+ }
+ }
+}
+
+
+
+