C#中如何知道 网络 通还是不通

lifeixie 2007-05-21 02:12:48
C#中如何知道 网络 通还是不通???
并不是 要知道能不能 上网这个所谓,那是路由器封的!!!如何知道 网络现在 通不通???
...全文
913 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
laneyu 2007-05-22
  • 打赏
  • 举报
回复
API的PING下
李洪喜 2007-05-22
  • 打赏
  • 举报
回复
比较简单的方法是创建一个webclient对象,连接一个比较大的网站,如果能连接上,就是通的。
Qim 2007-05-22
  • 打赏
  • 举报
回复
学习.
coolpc 2007-05-22
  • 打赏
  • 举报
回复
API里的ping^……
littlegang 2007-05-22
  • 打赏
  • 举报
回复
你的服务器是不是IP地址不固定?
lifeixie 2007-05-21
  • 打赏
  • 举报
回复
对于拔除网线造成的网络通讯故障!是 没什么问题的!拔 4个小时 插上 服务器端照样可以连上,可是 其他情况造成战时不通畅!
然后等网络通畅了之后,客户端就连不上我服务器了,重新启动服务也不行,必须把软件 重新启动才行!不知道是不是内部 自动把套节字销毁了!
所以只有 判断网络不通的情况下,马上停止服务,然后 知道战士不通,然后知道后,等好了后启动服务!!!
JavaK 2007-05-21
  • 打赏
  • 举报
回复
如是2003用C#调cmd--ping, 是2005就更好办了直接用Ping了。
北京的雾霾天 2007-05-21
  • 打赏
  • 举报
回复
如下试试看:
public static void SimplePing ()
{
Ping pingSender = new Ping ();
PingReply reply = pingSender.Send (IPAddress);

if (reply.Status == IPStatus.Success)
{
Console.WriteLine ("Address: {0}", reply.Address.ToString ());
Console.WriteLine ("RoundTrip time: {0}", reply.RoundtripTime);
Console.WriteLine ("Time to live: {0}", reply.Options.Ttl);
Console.WriteLine ("Don't fragment: {0}", reply.Options.DontFragment);
Console.WriteLine ("Buffer size: {0}", reply.Buffer.Length);
}
else
{
Console.WriteLine (reply.Status);
}
}
liuguozhong 2007-05-21
  • 打赏
  • 举报
回复
/*检查连接网络情况
p_strIP - 服务器ip地址,
p_intPort - 待检测服务器端口号
*/
private static bool checkNetwork(string p_strIP,int p_intPort)
{
bool isReady = false;//返回值(网络是否通畅)

IPAddress ip = IPAddress.Parse(p_strIP);
IPEndPoint ipes = new IPEndPoint(ip, p_intPort);
Socket sockets = new Socket(ipes.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
sockets.Connect(ipes);//连接到指定地址簇
if (sockets.Connected)//获取连接状态
isReady = true;
}
catch (Exception e)
{
//@连接错误
}
return isReady;
}
ASDC001 2007-05-21
  • 打赏
  • 举报
回复
接上面:
private bool tryPing(IPEndPoint lep)
{
//do the ping
bool bResult = false;

//create an ICMP socket
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);

//set up ICMPHeader structure
ICMPHeader header = new ICMPHeader();
header.type = 8; //ICMP_ECHO type
header.code = 0;
header.id = Convert.ToUInt16(Process.GetCurrentProcess().Id); //lossy conversion
header.seq = 0;
header.chksum = 0;
DateTime startTime = DateTime.Now;
header.timestamp = Convert.ToUInt64(startTime.Ticks);



//fill header into byte array
byte[] arHeader = header.toByteArray();

//create the array which is to be sent
byte[] arBytes = new byte[arHeader.Length + 32];

byte fill = Convert.ToByte('E'); //arbitrary fill data to be sent

for(int i = 0; i < arBytes.Length; i++)
{
arBytes[i] = fill;
}

//copy header to array which is to be sent
arHeader.CopyTo(arBytes, 0);

header.chksum = this.generateIPChecksum(arBytes);
//now this is goofy because after we inserted the checksum into
//the header we have to recreate the byte array
arHeader = header.toByteArray();
arHeader.CopyTo(arBytes, 0);

sock.SendTo(arBytes, lep);

// check socket receive asnychronously and heed timeout
if(true == this.isSocketReadible(sock))
{

// Creates an IpEndPoint to capture the identity of the sending host.
IPEndPoint sender1 = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender1;

// Creates a byte buffer to receive the message.
byte[] receiveBuffer = new byte[1024];

// Receives datagram from a remote host. This call blocks!
int nReceived = sock.ReceiveFrom(receiveBuffer, ref tempRemoteEP);

bResult = this.verifyReceivedMessage(receiveBuffer, nReceived, arHeader.Length);

m_arTTL[m_idxPing] = receiveBuffer[8];
}
else
{
m_strErrorMessage = "Echoing socket is not readible in the given timeout";
}

//number of routing stations is part of the IP Header

//calculate elapsed time
DateTime now = DateTime.Now;
TimeSpan elapsedTime = new TimeSpan(now.Ticks - startTime.Ticks);
m_arTime[m_idxPing] = elapsedTime.Milliseconds;


return bResult;
}

private bool isIPAddress(string strAddress)
{
//return true if the address is an IP Address e.g. 192.168.8.111
//false points to a hostname like "INV111"
bool bResult = true;

foreach (char ch in strAddress)
{
if((false == Char.IsDigit(ch)) && (ch != '.'))
{
bResult = false;
break;
}
}

return bResult;
}

private ushort generateIPChecksum(byte[] arBytes)
{
//generate an IP checksum based on a given data buffer
ulong chksum = 0;

int nSize = arBytes.Length;
int i = 0;

while(nSize > 1)
{
chksum += (ulong)((((ushort)arBytes[i+1]) << 8) + (ushort)arBytes[i]);
nSize--;
nSize--;
i++;
i++;
}

if(nSize > 0)
{
chksum += arBytes[i];
}

chksum = (chksum >> 16) + (chksum & 0xffff);
chksum += (chksum >> 16);

ushort result = (ushort)(~chksum);
return result;
}

private bool isSocketReadible(Socket s)
{
//poll socket for data until timeout
bool bResult = false;
int n = 0;

while(n < m_Timeout)
{
if(true == s.Poll(1000, SelectMode.SelectRead)) //100 usec = 1 msec
{
bResult = true;
break;
}

n++;
}

return bResult;
}

private bool verifyReceivedMessage(byte[] arBytes, int nReceived, int minLengthSent)
{
//the first 4 bytes are the length of the IP Header in DWORDS
int nLengthIPHeader = arBytes[0] & 0x0f;
nLengthIPHeader *= 4; //in bytes

//enough data received
if(nLengthIPHeader + minLengthSent > nReceived)
{
m_strErrorMessage = "Not enough data echoed";
return false;
}

//check if it is an ICMP_ECHOREPLY packet
if(arBytes[nLengthIPHeader] != 0)
{
m_strErrorMessage = "Wrong type of telegram echoed";
return false;
}

int nId = arBytes[nLengthIPHeader + 6] + arBytes[nLengthIPHeader + 7] * 256;

//check echoed process id is ours
if(nId != Convert.ToUInt16(Process.GetCurrentProcess().Id)) //lossy conversion
{
m_strErrorMessage = "Received echoed data was not sent by this process";
return false;
}

return true;
}

private int calcAvgTime()
{
int result = 0;

foreach (int i in m_arTime)
{
result += i;
}

result /= m_arTime.Length;
return result;
}


private int calcAvgTTL()
{
int result = 0;

foreach (int i in m_arTTL)
{
//only count successful pings
if(m_arResults[i] == true)
{
result += i;
}
}

result /= m_arTTL.Length;
return result;
}

private void clearStats()
{
//clear statistical data
for(int i = 0; i < m_arTime.Length; i++)
{
m_arTime[i] = 0;
m_arTTL[i] = 0;
}
}
}
}
ASDC001 2007-05-21
  • 打赏
  • 举报
回复
以前是用API里的ping功能
现在c#应该封装得有ping功能,找找看。
检测是否连接上交换机,ping自己IP就可以。
是否连接上服务器,ping服务器啊
下面代码来自:http://www.iters.cn/html/2005-12/85.htm

C# Ping
By Gerhard Schmeusser


using System;
using System.Net;
using System.Diagnostics;
using System.Net.Sockets;
using System.Collections;

namespace cmpDWPing
{
///
//Implements an Ethernet Ping component
//Ping is part of the ICMP (Internet Control Message Protocol) which serves
//Hosts and Routers for the purpose of error messaging and exchanging status and commands.
//It is part of the IP protocol and therefore cannot be considered as reliable.
//The following ICMP messages are used here to implement a ping functionality:
//Echo Request
//Echo Answer


//The interface is pretty straightforward:
//the ping method performs the network ping and returns success or failure
//in case of failure ask the ErrorMessage property for the reason
//
// There are some properties which you can use for setting and getting information. See the interface below
//
//
//
//
//You can use this component as a COM object if
//you create a COM callable wrapper (CCW) by the following command line programs:

//the typelib is created by the project setting "register for COM interop":
//regasm bin/debug/cmpDWPing.dll
//if you also want to manually create a typelib use the following line
//regasm /tlb:cmpDWPing.tlb bin/debug/cmpDWPing.dll

//use the following lines to register the component in the global assembly cache
//gacutil /u cmpDWPing
//gacutil /i bin/debug/cmpDWPing.dll
//
//Beforehand justification: Because of the C-style design of the ICMP protocol data structures
//which are meant to be cast this way and that and therefore not very
//suitable to a strict language like C#, we have to
//adopt some pretty awkward code here.
///

interface IDWPing
{
short ping(string strHostName); // 1 = success, 0 = failure
int Timeout {set;} //default = 500msec
int Repeats {set;} //default = 0
int AvgTime {get;} //measured average response time
int AvgTTL {get;} //measured average number of routing nodes the ping traveled
string ErrorMessage {get;} //a verbose error message in case of failure
}

struct ICMPHeader
{
public byte type;
public byte code;
public ushort chksum;
public ushort id;
public ushort seq;
public ulong timestamp;

public byte[] toByteArray()
{
//If you know a better way to serialize this into a byte array, let me know
byte[] arResult = new byte[22];
arResult[0] = this.type;
arResult[1] = this.code;
arResult[2] = (byte)chksum;
arResult[3] = (byte)(chksum >> 8);
arResult[4] = (byte)(chksum >> 16);
arResult[5] = (byte)(chksum >> 24);
arResult[6] = (byte)id;
arResult[7] = (byte)(id >> 8);
arResult[8] = (byte)(id >> 16);
arResult[9] = (byte)(id >> 24);
arResult[10] = (byte)seq;
arResult[11] = (byte)(seq >> 8);
arResult[12] = (byte)(seq >> 16);
arResult[13] = (byte)(seq >> 24);
arResult[14] = (byte)timestamp;
arResult[15] = (byte)(timestamp >> 8);
arResult[16] = (byte)(timestamp >> 16);
arResult[17] = (byte)(timestamp >> 24);
arResult[18] = (byte)(timestamp >> 32);
arResult[19] = (byte)(timestamp >> 40);
arResult[20] = (byte)(timestamp >> 48);
arResult[21] = (byte)(timestamp >> 56);

return arResult;
}
}

public class CDWPing : IDWPing
{
private int m_Timeout; //in msec
private int[] m_arTime; //response times statistic
private bool[] m_arResults; //results of pings
private byte[] m_arTTL; //routing stations statistic
private int m_idxPing;
private string m_strErrorMessage;

//----------------------------------------------------



public int Timeout { set{ m_Timeout = MinMax.max(value, 1); }}
public int Repeats { set
{ int n = MinMax.max(value, 1);
m_arTime = new int[n];
m_arTTL = new byte[n];
m_arResults = new bool[n];
}
}
public int AvgTime { get{ return this.calcAvgTime(); }}
public int AvgTTL { get{ return this.calcAvgTTL(); }}
public string ErrorMessage { get{ return m_strErrorMessage; }}

public CDWPing()
{
m_arTime = new int[1]; //size of m_arTime is number of tries
m_arTTL = new Byte[1];
m_arResults = new bool[1];
m_strErrorMessage = "Don't know what happened";
m_Timeout = 500; //msec
}


public short ping(string strHostName)
{
m_strErrorMessage = "No error occured";

this.clearStats();

short result = 0;

//convert strHostName to an IPEndPoint
try
{
IPEndPoint lep;

//check if strHostname is already a dotted address
//and create an IPEndpoint from it
//note: port 7 is for echo but is irrelevant because of the socket type we are going to use
const int echoPort = 7;

if(true == this.isIPAddress(strHostName))
{
IPAddress ipAddr = IPAddress.Parse(strHostName);
lep = new IPEndPoint(ipAddr, echoPort);
}
else
{
IPHostEntry lipa = Dns.Resolve(strHostName);
lep = new IPEndPoint(lipa.AddressList[0], echoPort);
}

//number of tries
for(m_idxPing = 0; m_idxPing < m_arTime.Length; m_idxPing++)
{
if(true == tryPing(lep))
{
m_arResults[m_idxPing] = true;
result = 1; //one successful ping = overall success
}
else
{
m_arResults[m_idxPing] = false;
}
}
}
catch(SocketException ex)
{
result = 0;
m_strErrorMessage = ex.Message;
}
catch(Exception ex )
{
result = 0;
m_strErrorMessage = ex.Message;
}

return result;
}

Red_angelX 2007-05-21
  • 打赏
  • 举报
回复
检测计算机的 Internet 连接状态

检测计算机是否联网比较简单的做法可以通过一个 Win32 Internet(WinInet)
函数 InternetCheckConnection来实现;

这个函数的功能是检查是否能够建立 Internet 连接。

它的实现是在 %SystemRoot%\System32\wininet.dll 中,Delphi 调用声明在 WinInet.pas 中,

其 API 声明如下:

BOOL InternetCheckConnection(

IN LPCSTR lpszUrl,

IN DWORD dwFlags,

IN DWORD dwReserved

);

参数的意义是:

lpszUrl: 需要测试能否建立连接的 URL 地址,可以为空;

dwFlags: 目前只能是 FLAG_ICC_FORCE_CONNECTION(这个常量 Delphi 中没有声明,其值为 $00000001);

dwReserved: 目前只能为 0。

调用的说明:

如果 lpszUrl 是非空的,Windows 从中解析出 Host 名然后 Ping 这个指定的 Host。

如果 lpszUrl 是空的,并且 WinInet 内部服务器的 database 中有一个关于最近的 Server 的纪录,
Windows 就从这条纪录中解析出 Host 名然后 Ping 它。

如果能够成功的连接返回 True,否则返回 False;

以下是一个判断当前计算机是否联网的例子:

procedure TForm1.Button1Click(Sender: TObject);

begin

if InternetCheckConnection('http://www.yahoo.com/', 1, 0) then

edit1.text:= 'Connected'

else

edit1.text:= 'Disconnected';

end;

通过上述的方法只能检测出当前计算机是否物理联网,即网线是否接好,网卡是否能顺利工作,
不能确定是否能够实现获得 Internet 服务,即是否能和 ISP 进行 Internet 连接。

这时可以通过另一个 Win32 Internet(WinInet) 函数 InternetQueryOption 来检测;

这个函数的功能是查询指定 Internet 句柄的状态、选项。

其 API 声明如下:

BOOL InternetQueryOption(

IN HINTERNET hInternet,

IN DWORD dwOption,

OUT LPVOID lpBuffer,

IN OUT LPDWORD lpdwBufferLength

);

参数的意义是:

hInternet:查询对象的 Internet 句柄(全局查询时为 nil),

dwOption:查询的项目;

lpBuffer:返回的查询结果;

lpdwBufferLength:查询结果的字节长度(包括 IN 和 OUT);

查询成功返回 True,否则返回 False;

我们要查询当前计算机的 Internet 连接状态时可以使用查询项目 INTERNET_OPTION_CONNECTED_STATE,

得到的 ConnectState 返回值可能是以下值的一个或几个值之和:

INTERNET_STATE_CONNECTED :$00000001 连接状态;

INTERNET_STATE_DISCONNECTED :$00000002 非连接状态(和 INTERNET_STATE_CONNECTED 对应);

INTERNET_STATE_DISCONNECTED_BY_USER :$00000010 用户请求的非连接状态

INTERNET_STATE_IDLE :$00000100 连接状态,并且空闲

INTERNET_STATE_BUSY :$00000200 连接状态,正在响应连接请求

以下是一个判断当前计算机是否可以获得 Internet 服务的例子:

function TForm1.CheckOffline: boolean;

var

ConnectState: DWORD;

StateSize: DWORD;

begin

ConnectState:= 0;

StateSize:= SizeOf(ConnectState);

result:= false;

if InternetQueryOption(nil, INTERNET_OPTION_CONNECTED_STATE, @ConnectState, StateSize) then

if (ConnectState and INTERNET_STATE_DISCONNECTED) <> 2 then result:= true;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

if CheckOffline then

edit1.text:= 'Connect To ISP'

else

edit1.text:= 'Disconnect To ISP';

end;

需要说明的是 InternetQueryOption 函数的检测结果只能表明当前的 Internet 设置是可用的,

并不能表示计算机一定能访问 Internet,例如网线掉了,网卡突然坏了之类的错误就没法检测出来,

要想检测当前计算机是否能够获得 Internet 服务了必须两个函数结合起来使用。
falaowang 2007-05-21
  • 打赏
  • 举报
回复
不能用ping吗?直接写个ping 类
Red_angelX 2007-05-21
  • 打赏
  • 举报
回复
WinSock 对于拔除网线造成的网络通讯故障并没有什么处理措施,只能等待超时出错……

.net Framework 提供了两种方法,让我们能做些额外的补救。

1. Microsoft.VisualBasic.Devices.Network


Network net = new Network()
Console.WriteLine(net.IsAvailable);


2. System.Net.NetworkInformation.NetworkChange


NetworkChange.NetworkAvailabilityChanged += delegate(object sender, NetworkAvailabilityEventArgs e) { Console.WriteLine(e.IsAvailable); };
Red_angelX 2007-05-21
  • 打赏
  • 举报
回复
可以 有个api 我找下

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧