用户
购买联系
定制软件
智动博客助手
智动终级刷IP工具
首页
首页
/
编程技术
如何实现连续的PING
时间:
2010年04月12日
点击:
379
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
System.Net;
using
System.Net.Sockets;
namespace
Ping
...
{
/**/
///
<summary>
///
Form1 的摘要说明。
///
</summary>
///
public
class
Form1 : System.Windows.Forms.Form
...
{
private
System.Windows.Forms.Label label1;
private
System.Windows.Forms.TextBox textBox1;
private
System.Windows.Forms.Button button1;
private
System.Windows.Forms.RichTextBox richTextBox1;
/**/
///
<summary>
///
必需的设计器变量。
///
</summary>
private
System.ComponentModel.Container components
=
null
;
public
Form1()
...
{
//
//
Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
//
TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/**/
///
<summary>
///
清理所有正在使用的资源。
///
</summary>
protected
override
void
Dispose(
bool
disposing )
...
{
if
( disposing )
...
{
if
(components
!=
null
)
...
{
components.Dispose();
}
}
base
.Dispose( disposing );
}
Windows 窗体设计器生成的代码
#region
Windows 窗体设计器生成的代码
/**/
///
<summary>
///
设计器支持所需的方法 - 不要使用代码编辑器修改
///
此方法的内容。
///
</summary>
private
void
InitializeComponent()
...
{
this
.label1
=
new
System.Windows.Forms.Label();
this
.textBox1
=
new
System.Windows.Forms.TextBox();
this
.button1
=
new
System.Windows.Forms.Button();
this
.richTextBox1
=
new
System.Windows.Forms.RichTextBox();
this
.SuspendLayout();
//
//
label1
//
this
.label1.Location
=
new
System.Drawing.Point(
8
,
16
);
this
.label1.Name
=
"
label1
"
;
this
.label1.Size
=
new
System.Drawing.Size(
80
,
16
);
this
.label1.TabIndex
=
0
;
this
.label1.Text
=
"
目标主机名:
"
;
//
//
textBox1
//
this
.textBox1.Location
=
new
System.Drawing.Point(
96
,
16
);
this
.textBox1.Name
=
"
textBox1
"
;
this
.textBox1.Size
=
new
System.Drawing.Size(
152
,
21
);
this
.textBox1.TabIndex
=
1
;
this
.textBox1.Text
=
"
127.0.0.1
"
;
//
//
button1
//
this
.button1.Location
=
new
System.Drawing.Point(
256
,
16
);
this
.button1.Name
=
"
button1
"
;
this
.button1.Size
=
new
System.Drawing.Size(
96
,
23
);
this
.button1.TabIndex
=
2
;
this
.button1.Text
=
"
Ping
"
;
this
.button1.Click
+=
new
System.EventHandler(
this
.button1_Click);
//
//
richTextBox1
//
this
.richTextBox1.Location
=
new
System.Drawing.Point(
8
,
48
);
this
.richTextBox1.Name
=
"
richTextBox1
"
;
this
.richTextBox1.Size
=
new
System.Drawing.Size(
344
,
184
);
this
.richTextBox1.TabIndex
=
3
;
this
.richTextBox1.Text
=
""
;
//
//
Form1
//
this
.AutoScaleBaseSize
=
new
System.Drawing.Size(
6
,
14
);
this
.ClientSize
=
new
System.Drawing.Size(
360
,
238
);
this
.Controls.Add(
this
.richTextBox1);
this
.Controls.Add(
this
.button1);
this
.Controls.Add(
this
.textBox1);
this
.Controls.Add(
this
.label1);
this
.MaximizeBox
=
false
;
this
.Name
=
"
Form1
"
;
this
.StartPosition
=
System.Windows.Forms.FormStartPosition.CenterScreen;
this
.Text
=
"
演示执行PING
"
;
this
.ResumeLayout(
false
);
}
#endregion
/**/
///
<summary>
///
应用程序的主入口点。
///
</summary>
[STAThread]
static
void
Main()
...
{
Application.Run(
new
Form1());
}
//
声明常量
const
int
SOCKET_ERROR
=
-
1
;
const
int
ICMP_ECHO
=
8
;
public
static
Int32 Serialize( IcmpPacket packet, Byte [] Buffer, Int32 PacketSize, Int32 PingData )
...
{
//
取得报文内容,转化为字节数组,然后计算报文的长度
Int32 cbReturn
=
0
;
//
数据报结构转化为数组
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);
Array.Copy( b_type,
0
, Buffer, Index, b_type.Length );
Index
+=
b_type.Length;
Array.Copy( b_code,
0
, Buffer, Index, b_code.Length );
Index
+=
b_code.Length;
Array.Copy( b_cksum,
0
, Buffer, Index, b_cksum.Length );
Index
+=
b_cksum.Length;
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;
//
复制数据
Array.Copy( packet.Data,
0
, Buffer, Index, PingData );
Index
+=
PingData;
if
( Index
!=
PacketSize
/**/
/*
sizeof(IcmpPacket)
*/
)
...
{
cbReturn
=
-
1
;
return
cbReturn;
}
cbReturn
=
Index;
return
cbReturn;
}
/**/
///
<summary>
///
校验和算法
///
</summary>
public
static
UInt16 checksum( UInt16[] buffer,
int
size )
...
{
Int32 cksum
=
0
;
int
counter;
counter
=
0
;
/**/
/*
把ICMP报头二进制数据以2字节为单位累加起来
*/
while
( size
>
0
)
...
{
UInt16 val
=
buffer[counter];
cksum
+=
Convert.ToInt32( buffer[counter] );
counter
+=
1
;
size
-=
1
;
}
/**/
/*
若ICMP报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个
* 2字节数据的高字节,这个2字节数据的低字节为0,继续累加
*/
cksum
=
(cksum
>>
16
)
+
(cksum
&
0xffff
);
cksum
+=
(cksum
>>
16
);
return
(UInt16)(
~
cksum);
}
private
void
button1_Click(
object
sender, System.EventArgs e)
...
{
//
执行PING
this
.richTextBox1.Text
=
""
;
for
(
int
p
=
0
;p
<
10
;p
++
)
...
{
try
...
{
string
HostName
=
this
.textBox1.Text;
int
nBytes
=
0
;
int
dwStart
=
0
, dwStop
=
0
;
//
初始化一个ICMP类型的Socket
Socket socket
=
new
Socket(AddressFamily.InterNetwork , SocketType.Raw, ProtocolType.Icmp);
//
取得目标主机的主机名
IPHostEntry serverHE
=
Dns.GetHostByName(HostName);
IPEndPoint ipepServer
=
new
IPEndPoint(serverHE.AddressList[
0
],
0
);
EndPoint epServer
=
(ipepServer);
IPHostEntry fromHE
=
Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom
=
new
IPEndPoint(fromHE.AddressList[
0
],
0
);
EndPoint EndPointFrom
=
(ipEndPointFrom);
int
PacketSize
=
0
;
IcmpPacket packet
=
new
IcmpPacket();
//
构造数据报
packet.Type
=
ICMP_ECHO;
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];
//
初始化 Packet.Data
for
(
int
i
=
0
; i
<
PingData; i
++
)
...
{
packet.Data[i]
=
(
byte
)
'
#
'
;
}
//
保存数据报的长度
PacketSize
=
PingData
+
8
;
Byte [] icmp_pkt_buffer
=
new
Byte[ PacketSize ];
Int32 Index
=
0
;
//
调用Serialize方法
//
报文总共的字节数
Index
=
Serialize(
packet,
icmp_pkt_buffer,
PacketSize,
PingData );
if
( Index
==
-
1
)
...
{
this
.richTextBox1.Text
+=
"
报文大小有错!\n
"
;
return
;
}
//
转化为Uint16类型的数组,取得数据报长度的一半
Double double_length
=
Convert.ToDouble(Index);
Double dtemp
=
Math.Ceiling( double_length
/
2
);
int
cksum_buffer_length
=
Convert.ToInt32(dtemp);
//
生成一个字节数组
UInt16 [] cksum_buffer
=
new
UInt16[cksum_buffer_length];
//
初始化 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
;
}
//
调用checksum,返回检查和
UInt16 u_cksum
=
checksum(cksum_buffer, cksum_buffer_length);
//
检查和存在报文中
packet.CheckSum
=
u_cksum;
Byte [] sendbuf
=
new
Byte[ PacketSize ];
//
再次检查报文大小
Index
=
Serialize(
packet,
sendbuf,
PacketSize,
PingData );
//
如果有错,则报告错误
if
( Index
==
-
1
)
...
{
this
.richTextBox1.Text
+=
"
报文大小有错!\n
"
;
return
;
}
dwStart
=
System.Environment.TickCount;
//
开始时间
//
用socket发送数据报
if
((nBytes
=
socket.SendTo(sendbuf, PacketSize,
0
, epServer))
==
SOCKET_ERROR)
...
{
this
.richTextBox1.Text
+=
"
不能发送数据包! \n
"
;
}
//
初始化缓冲区.接受缓冲区
//
ICMP 头 +IP 头 (20 字节)
Byte [] ReceiveBuffer
=
new
Byte[
256
];
nBytes
=
0
;
//
接受字节流
bool
recd
=
false
;
int
timeout
=
0
;
//
循环检查目标主机响应时间
while
(
!
recd)
...
{
nBytes
=
socket.ReceiveFrom(ReceiveBuffer,
256
,
0
,
ref
EndPointFrom);
if
(nBytes
==
SOCKET_ERROR)
...
{
this
.richTextBox1.Text
+=
"
目标主机没有响应!\n
"
;
recd
=
true
;
break
;
}
else
if
(nBytes
>
0
)
...
{
dwStop
=
System.Environment.TickCount
-
dwStart;
this
.richTextBox1.Text
+=
"
数据来自主机:
"
+
this
.textBox1.Text
+
"
,收到的字节数:
"
+
nBytes
+
"
, 耗时:
"
+
dwStop
+
"
ms \n
"
;
recd
=
true
;
break
;
}
timeout
=
System.Environment.TickCount
-
dwStart;
if
(timeout
>
1000
)
...
{
this
.richTextBox1.Text
+=
"
连接超时! \n
"
;
recd
=
true
;
}
}
//
关闭socket
socket.Close();
}
catch
(Exception Err)
...
{
MessageBox.Show(
"
PING目标主机操作失败!错误信息是:
"
+
Err.Message,
"
信息提示
"
,MessageBoxButtons.OK,MessageBoxIcon.Information);
return
;
}
}
}
}
public
class
IcmpPacket
...
{
public
Byte Type;
//
消息类型
public
Byte SubCode;
//
子码类型
public
UInt16 CheckSum;
//
校检和
public
UInt16 Identifier;
//
标志符
public
UInt16 SequenceNumber;
//
顺序号
public
Byte [] Data;
//
数据
}
//
ICMP包
}
更多DotNet好文章www.zdexe.com
赞助商链接
热门内容
Navicat 中读取MYSQL数据显中文乱码问题解决方法
Proguard混淆提示类重复(Duplicate zip entry等提示)
phpstorm不安装apache就可以本地测试PHP
C# ListView随窗体大小自动改变列宽
MSScriptControl详解(可实现在C#等语言中调用JAVASCRIPT代码)
C#出现A generic error occurred in GDI+问题分析与解决
C#如何将控件设置为透明效果
钩子(HOOK)函数教程(一)
C#时常需要调用C++DLL问题详解
目录未找到或者无法访问:“ ./data/template”的解决
Sqlite:一个SQL搞定,记录存在不插入或者替换数据
C#实现自定义外观并可拖动和改变大小的窗口
相关内容
Android 实现模拟按键,模拟操作
Sqlite:一个SQL搞定,记录存在不插入或者替换数据
Nginx伪静态配置和常用Rewrite伪静态规则集锦
MQTT协议简要介绍
Navicat 中读取MYSQL数据显中文乱码问题解决方法
phpstorm不安装apache就可以本地测试PHP
Proguard混淆提示类重复(Duplicate zip entry等提示)
Android权限设置总汇
C#出现A generic error occurred in GDI+问题分析与解决
SQLite 简介
用PHP操作sqlite数据库
用JAVA操作SQLite
我们的产品
智动终极刷IP工具
智动博客助手
智动邮件搜索
联系我们
copyright © 2008 - 2021
智动软件
关于我们
联系我们
代理合作
投诉建议
常见问题
常用组件下载