Programación de sockets para implementar ping
C#:
clase Ping
{
const int SOCKET_ERROR = -1
const int ICMP_ECHO; = 8;
OnPingLog estático público onpinglog=null;
PingLog estático protegido plog=new PingLog()
WirteLog estático público (cadena s)
{
Ping.plog.writelog(s);
if(onpinglog!=null)
{
onpinglog(s);
}
}
suma de comprobación UInt16 estática pública (búfer UInt16[], tamaño int)
{
Int32 cksum = 0;
int contador = 0;
mientras (sizegt; 0)
{
UInt16 val = buffer[contador];
cksum = Convert.ToInt32(buffer[contador]);
contador
tamaño--;
}
cksum = (cksum gt; gt; 16) (cksum amp; 0xffff);
cksum = (cksum gt; gt; 16);
return (UInt16)(~cksum);
}
public static Int32 Serialize(paquete IcmpPacket, Byte[] Buffer, Int32 PacketSize, Int32 PingData)
{
Int32 cbReturn = 0;
int Índice = 0;
Byte[] b_type = nuevo Byte[1];
b_type[0] = (paquete.Type);
Byte[] b_code = nuevo Byte[1]
b_code[0] = (paquete .SubCode);
Byte[] b_cksum =
BitConverter.GetBytes(packet.CheckSum);
Byte[] b_id = BitConverter.GetBytes(packet.Identifier);
Byte[] b_seq = BitConverter.GetBytes(packet.SequenceNumber)
Array.Copy(b_type, 0, Buffer, Índice, b_type.Length
Índice = b_type.Length
Array.Copy(b_code); , 0, Búfer, Índice, b_code.Length);
Índice = b_code.Length
Array.Copy(b_cksum, 0, Búfer, Índice, b_cksum.Length); /p>
Índice = b_cksum.Length;
Array.Copy(b_id, 0, Buffer, Índice, b_id.Length);
Índice = b_id.Length; /p>
Array.Copy(b_seq, 0, Buffer, Índice, b_seq.Length
Índice = b_seq.Length
Array.Copy(packet.Data); , 0, Búfer, Índice, PingData);
Índice = PingData
if(Índice != Tamaño del paquete)
{
cbReturn = -1;
devuelve cbReturn
}
cbReturn = Índice
devuelve cbReturn
}
public static void PingHost(host de cadena)
{
servidor IPHostEntryHE, fromHE
int nBytes = 0; /p>
int dwStart = 0;
int dwStop = 0;
Socket socket = nuevo Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); /p>
prueba
{
//serverHE = Dns.GetHost
ByName(host);
servidorHE = Dns.GetHostByAddress(host.Split(':')[0]);
}
catch(Exception)
{
WirteLog("host de destino" host "no existe");
retorno
}
//Puerto de prueba
// int portNum = 0
// if(host.Split(':').Length gt; 1)
// {
// portNum = Int32.Parse(host.Split(':')[1]);
// }
// else
// {
// portNum = 13
// }
// cadena hostName = host; . Split(':')[0];
// prueba
// {
// Cliente TcpClient = nuevo TcpClient(nombre de host, número de puerto) ;
// cliente.Close();
// }
// captura (Excepción e)
// {
// WirteLog("Error: " host e.Message "");
// socket.Close()
// return;
// p>
// }
IPEndPoint ipepServer;
if(host.Split(':').Length gt; 1)
{
ipepServer = new IPEndPoint(serverHE.AddressList[0], Int32.Parse(host.Split(':')[1])); > }
else
{
ipepServer = new IPEndPoint(serverHE.AddressList[0],
}); p>
EndPoint epServer = (ipepServer);
fromHE = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom
si (host.Split(':' ).Length == 1)
{
ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0],
<); p> }más
{
>
ipEndPointFrom = nuevo IPEndPoint(fromHE.AddressList[0], Int32.Parse(host.Split(':')[1]));
}
EndPoint EndPointFrom = (ipEndPointFrom);
int PacketSize = 0;
paquete IcmpPacket = nuevo
paquete.Type = ICMP_ECHO
;paquete.SubCode = 0;
paquete.CheckSum = UInt16.Parse("0");
paquete.Identificador = UInt16.Parse("45"); /p>
paquete.SequenceNumber = UInt16.Parse("0");
int PingData = 32
paquete.Data = nuevo Byte[PingData]; p>
p>
for(int i=0; ilt; PingData; i )
{
paquete.Datos[i] = (byte)'# ';
}
Tamaño del paquete = PingData 8
Byte[] icmp_pkt_buffer = nuevo Byte[Tamaño del paquete]
Int32 Index = 0;
Índice = Serializar(paquete, icmp_pkt_buffer, Tamaño del paquete, PingData
if(Índice == -1)
{
<); p> WirteLog(" Error (Error al crear el paquete)");return
}
Double double_length = Convert.ToDouble(Index); /p>
Double dtemp = Math.Ceiling(double_length/2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
UInt16[] cksum_buffer = new UInt16[ cksum_buffer_length];
p>
int icmp_header_buffer_index = 0;
for(int i=0; ilt; cksum_buffer_length; i )
{
cksum_buffer[i] = BitConverter.ToUInt16(icmp_pkt_buffer, icmp_header_buffer_index); /p>
icmp_header_buffer_index = 2;
}
UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length
paquete.CheckSum = u_cksum ; p>
p>
Byte[] sendbuf = nuevo Byte[PacketSize];
Índice = Serialize(packet, sendbuf, PacketSize, PingData
if(); Índice == -1 )
{
WirteLog("Error (Error al crear el paquete)"); }
dwStart = System.Environment.TickCount;
if((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR)
{ p>
WirteLog("Error (Error de socket no se puede enviar el paquete)");
}
Byte[] ReceiverBuffer = nuevo Byte[256]
nBytes = 0;
bool recd = false;
int timeout = 0
while(!recd)
p>{
nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom
if(nBytes == SOCKET_ERROR)
{
WirteLog("Error (el host remoto no respondió)");
recd = true;
else if(nBytes gt; 0)
{
dwStop = Sistema
m.Environment.TickCount - dwStart;
WirteLog("Éxito (Respuesta de " epServer.ToString() ": bytes = " nBytes.ToString() " time = " dwStop "ms)"); /p>
recd = true;
descanso
}
tiempo de espera = System.Environment.TickCount - dwStart; > if(tiempo de espera gt; 1000)
{
WirteLog("Error (tiempo de espera)");
recd = true; > }
}
socket.Close();
}
}
clase pública IcmpPacket
{
public IcmpPacket()
{
//
// TODO: Agregar aquí Lógica del constructor
//
}
Tipo de byte público
Subcódigo de byte público
Suma de comprobación UInt16 pública;
Identificador UInt16 público
Número de secuencia UInt16 público
Byte público [] Datos
}