C#如何判断一个远程连接是否存在???

zqs1002 2011-10-11 08:18:00
如何用C#,如何判断Web Service 到远程实时数据库是否存在??

注意了,不是要用Socket建立连接,而是判断是否存在这个连接??
...全文
832 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
VCS_starter 2013-05-23
  • 打赏
  • 举报
回复
绝对顶楼主。。。
tianlongk 2013-03-19
  • 打赏
  • 举报
回复
查找与楼主提问相关的资料,感谢楼主找到资料还回复到此帖子,收获不小!
alexfeng1 2012-01-08
  • 打赏
  • 举报
回复
學到了不少,
小弟受教了
zqs1002 2011-10-13
  • 打赏
  • 举报
回复
主要参考了这个帖子:
http://www.cnblogs.com/yulinlover/archive/2009/02/08/1911862.html

新建一个类IsConnected,加入如下代码;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.InteropServices;

namespace eXtremeSQLwcfws
{
public class IsConnected
{
/// <summary>
/// 检查远程主机与本机是否存在连接
/// </summary>
/// <param name="host">远程主机的IP</param>
/// <param name="port">远程主机的PORT</param>
/// <returns></returns>
public static int CheckConnected(string host, string port)
{
try
{
MIB_TCPTABLE tcpTableData = new MIB_TCPTABLE();
tcpTableData = GetTcpTableInfo();
for (int i = 0; i < tcpTableData.dwNumEntries; i++)
{
string i_p = GetIpAddress(tcpTableData.table[i].dwRemoteAddr) + ":" + GetTcpPort(tcpTableData.table[i].dwRemotePort).ToString();

if (i_p == host + ":" + port) return tcpTableData.table[i].dwState;
}
}
catch (Exception)
{ }

return 0;
}

[StructLayout(LayoutKind.Sequential)]
public class MIB_TCPROW
{
public int dwState;
public int dwLocalAddr;
public int dwLocalPort;
public int dwRemoteAddr;
public int dwRemotePort;
}

[StructLayout(LayoutKind.Sequential)]
public class MIB_TCPTABLE
{
public int dwNumEntries;
public MIB_TCPROW[] table;
}

protected static string GetIpAddress(long ipAddrs)
{
try
{
System.Net.IPAddress ipAddress = new System.Net.IPAddress(ipAddrs);
return ipAddress.ToString();
}
catch
{ return ipAddrs.ToString(); }

}

[DllImport("Ws2_32.dll")]
static extern ushort ntohs(ushort netshort);

protected static ushort GetTcpPort(int tcpPort)
{
return ntohs((ushort)tcpPort);
}

[DllImport("Iphlpapi.dll")]
static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder);

protected static MIB_TCPTABLE GetTcpTableInfo()
{
//声明一个指针准备接受Tcp连接信息
IntPtr hTcpTableData = IntPtr.Zero;
//声明hTcpTableData指针所指向的内存缓冲区大小
int iBufferSize = 0;
//声明MIB_TCPTABLE对象,作为返回值
MIB_TCPTABLE tcpTable = new MIB_TCPTABLE();

//声明一个List对象来临时存放MIB_TCPROW对象
List<MIB_TCPROW> lstTcpRows = new List<MIB_TCPROW>();

//调用API来获得真正的缓冲区大小,iBufferSize默认为0,
//这时调用API GetTcpTable会触发一个异常ERROR_INSUFFICIENT_BUFFER
//通过这个异常系统会把真正的缓冲长度返回
GetTcpTable(hTcpTableData, ref iBufferSize, false);
//为托管指针在堆上分配内存
hTcpTableData = Marshal.AllocHGlobal(iBufferSize);
//求得MIB_TCPROW对象的内存字节数
int iTcpRowLen = Marshal.SizeOf(typeof(MIB_TCPROW));
//根据上面得到的缓冲区大小来推算MIB_TCPTABLE里的MIB_TCPROW数组长度
//下面用缓冲长度-sizeof(int)也就是去掉MIB_TCPTABLE里的成员dwNumEntries所占用的内存字节数
int aryTcpRowLength = (int)Math.Ceiling((double)(iBufferSize - sizeof(int)) / iTcpRowLen);
//重新取得TcpTable的数据
GetTcpTable(hTcpTableData, ref iBufferSize, false);
//下面是关键,由于MIB_TCPTABLE里的成员有一个是数组,而这个数组长度起初我们是不能确定的
//所以这里我们只能根据分配的指针来进行一些运算来推算出我们所要的数据
for (int i = 0; i < aryTcpRowLength; i++)
{
//hTcpTableData是指向MIB_TCPTABLE缓冲区的内存起始区域,由于其成员数据在内存中是顺序排列
//所以我们可以推断hTcpTableData+4(也就是sizeof(dwNumEntries)的长度)后就是MIB_TCPROW数组的第一个元素
IntPtr hTempTableRow = new IntPtr(hTcpTableData.ToInt32() + 4 + i * iTcpRowLen);
MIB_TCPROW tcpRow = new MIB_TCPROW();
tcpRow.dwLocalAddr = 0;
tcpRow.dwLocalPort = 0;
tcpRow.dwRemoteAddr = 0;
tcpRow.dwRemotePort = 0;
tcpRow.dwState = 0;
//把指针数据拷贝到我们的结构对象里。
Marshal.PtrToStructure(hTempTableRow, tcpRow);
lstTcpRows.Add(tcpRow);
}
tcpTable.dwNumEntries = lstTcpRows.Count;
tcpTable.table = new MIB_TCPROW[lstTcpRows.Count];
lstTcpRows.CopyTo(tcpTable.table);
return tcpTable;
}
}
}

调用IsConnected.CheckConnected(ip,port)
返回5,连接存在且正常;返回0,连接不存在,此时需要新建一个连接;其它返回值参考以下链接
http://msdn.microsoft.com/zh-cn/library/aa366909(v=VS.85).aspx
zqs1002 2011-10-13
  • 打赏
  • 举报
回复
简化一下代码;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.InteropServices;

namespace eXtremeSQLwcfws
{
public class IsConnected
{
/// <summary>
/// 检查远程主机与本机是否存在连接
/// </summary>
/// <param name="host">远程主机的IP</param>
/// <param name="port">远程主机的PORT</param>
/// <returns></returns>
public static int CheckConnected(string host, string port)
{
List<MIB_TCPROW> lstTcpRows = new List<MIB_TCPROW>();
int dwNumEntries = 0;

GetTcpTableInfo(ref dwNumEntries, ref lstTcpRows);

for (int i = 0; i < dwNumEntries; i++)
{
string st = GetIpAddress(lstTcpRows[i].dwRemoteAddr) + ":" + GetTcpPort(lstTcpRows[i].dwRemotePort).ToString();
if (st == host + ":" + port) return lstTcpRows[i].dwState;
}

return 0;
}

[StructLayout(LayoutKind.Sequential)]
public class MIB_TCPROW
{
public int dwState;
public int dwLocalAddr;
public int dwLocalPort;
public int dwRemoteAddr;
public int dwRemotePort;
}

protected static string GetIpAddress(long ipAddrs)
{
try
{
System.Net.IPAddress ipAddress = new System.Net.IPAddress(ipAddrs);
return ipAddress.ToString();
}
catch
{ return ipAddrs.ToString(); }
}

[DllImport("Ws2_32.dll")]
static extern ushort ntohs(ushort netshort);

protected static ushort GetTcpPort(int tcpPort)
{
return ntohs((ushort)tcpPort);
}

[DllImport("Iphlpapi.dll")]
static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder);

protected static void GetTcpTableInfo(ref int dwNumEntries, ref List<MIB_TCPROW> lstTcpRows)
{
//声明一个指针准备接受Tcp连接信息
IntPtr hTcpTableData = IntPtr.Zero;
//声明hTcpTableData指针所指向的内存缓冲区大小
int iBufferSize = 0;

//调用API来获得真正的缓冲区大小,iBufferSize默认为0,
//这时调用API GetTcpTable会触发一个异常ERROR_INSUFFICIENT_BUFFER
//通过这个异常系统会把真正的缓冲长度返回
GetTcpTable(hTcpTableData, ref iBufferSize, false);

//为托管指针在堆上分配内存
hTcpTableData = Marshal.AllocHGlobal(iBufferSize);

//求得MIB_TCPROW对象的内存字节数
int iTcpRowLen = Marshal.SizeOf(typeof(MIB_TCPROW));
//根据上面得到的缓冲区大小来推算MIB_TCPTABLE里的MIB_TCPROW数组长度
int aryTcpRowLength = (int)Math.Ceiling((double)(iBufferSize - sizeof(int)) / iTcpRowLen);

//重新取得TcpTable的数据
GetTcpTable(hTcpTableData, ref iBufferSize, false);

for (int i = 0; i < aryTcpRowLength; i++)
{
MIB_TCPROW tcpRow = new MIB_TCPROW();
tcpRow = (MIB_TCPROW)Marshal.PtrToStructure(hTcpTableData + sizeof(int) + i * iTcpRowLen, typeof(MIB_TCPROW));
lstTcpRows.Add(tcpRow);
}

dwNumEntries = lstTcpRows.Count;

}
}
}
threenewbee 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zqs1002 的回复:]
引用 5 楼 caozhy 的回复:
引用 4 楼 zqs1002 的回复:
引用 3 楼 caozhy 的回复:
连接、等待、如果超时说明不成功,在等待时间内返回说明成功。

没有办法可以确切知道连接是否存在。

原因很简单:(1)判断连接完成之后的瞬间网线被拔下,会出现报告成功却不成功的情况。(2)你没有办法判断在规定时间内得不到响应是因为连接不存在,还是连接存在但是没有来得及返……
[/Quote]

就是我说的办法,试探连接。
结婚兔 2011-10-12
  • 打赏
  • 举报
回复
帮顶 也想知道这个问题
zqs1002 2011-10-12
  • 打赏
  • 举报
回复
不要沉了
zqs1002 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xiaoyu821120 的回复:]
一般都是通过是否超时来判断,连接是不是存在,你觉得等的时间太长了,可以把超时时间改短一点。
[/Quote]

WCF Web Service (依托IIS的)在启动时建立一次连接,然后供其它接口使用;现在的问题是实时数据库有可能会挂掉(挂掉后有监控程序自动重新开启),但Web Service建立的连接也就断开了,我在Web Service启动时同时启动了一次定时器,定时检查此连接是不是存在,如果不存在就重新创建一个。

只要能像cport那样能监测远程连接的状态就可以了。
xiaoyu821120 2011-10-12
  • 打赏
  • 举报
回复
一般都是通过是否超时来判断,连接是不是存在,你觉得等的时间太长了,可以把超时时间改短一点。
zqs1002 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yangsonglint14 的回复:]
天回帖即可获得10分可用分!小
[/Quote]
哥们别打岔
funxu 2011-10-12
  • 打赏
  • 举报
回复
用wmi,查下msdn,里面有远程操作数据库的介绍
yangsonglinT14 2011-10-12
  • 打赏
  • 举报
回复
天回帖即可获得10分可用分!小
zqs1002 2011-10-12
  • 打赏
  • 举报
回复
等高手出现
zqs1002 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 caozhy 的回复:]
引用 4 楼 zqs1002 的回复:
引用 3 楼 caozhy 的回复:
连接、等待、如果超时说明不成功,在等待时间内返回说明成功。

没有办法可以确切知道连接是否存在。

原因很简单:(1)判断连接完成之后的瞬间网线被拔下,会出现报告成功却不成功的情况。(2)你没有办法判断在规定时间内得不到响应是因为连接不存在,还是连接存在但是没有来得及返回,或者连接上了,返回的数据丢失。

……
[/Quote]


不说这些道理,我就想知道cports.exe这种软件是怎样把网络连接的状态(已建立或不存在)抓出来的,告诉我用C#怎么实现??
zhoujianlong 2011-10-12
  • 打赏
  • 举报
回复
学习了
zqs1002 2011-10-12
  • 打赏
  • 举报
回复 1
有解决方法了,
比如要看本机是否与远程地址192.168.0.1:1521有连接,
用C#获取本机所有TCP连接中的远程IP和端口,返回字符串列表,如果有192.168.0.1:1521就说明本机与远程主机存在连接,否则就创建一个连接。

稍后把代码贴上来。
sxiangs 2011-10-12
  • 打赏
  • 举报
回复
学习了 呵呵
threenewbee 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zqs1002 的回复:]
引用 3 楼 caozhy 的回复:
连接、等待、如果超时说明不成功,在等待时间内返回说明成功。

没有办法可以确切知道连接是否存在。

原因很简单:(1)判断连接完成之后的瞬间网线被拔下,会出现报告成功却不成功的情况。(2)你没有办法判断在规定时间内得不到响应是因为连接不存在,还是连接存在但是没有来得及返回,或者连接上了,返回的数据丢失。


排除掉拔网线这些特殊的情况,如何通过……
[/Quote]
"拔网线"是一个生动的说法而已。事实上在验证返回,网络链路可能出现各种故障。

在通讯学里面有个著名的悖论,名字忘记了。说的是,两个通讯终端不可能依靠自身之间的通讯判断网络是否通畅。假设A发送一个消息给B,B收到以后给A确认A没有收到,或者B没有收到故没有给A确认,A是无法判断的。然后有人想,我们可以给确认加上确认的确认,但是确认的确认同样是不可靠的,这个过程可以无限循环下去。所以结论就是“两个通讯终端不可能依靠自身之间的通讯判断网络是否通畅”。
zqs1002 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 caozhy 的回复:]
连接、等待、如果超时说明不成功,在等待时间内返回说明成功。

没有办法可以确切知道连接是否存在。

原因很简单:(1)判断连接完成之后的瞬间网线被拔下,会出现报告成功却不成功的情况。(2)你没有办法判断在规定时间内得不到响应是因为连接不存在,还是连接存在但是没有来得及返回,或者连接上了,返回的数据丢失。
[/Quote]

排除掉拔网线这些特殊的情况,如何通过C#编程监测远程连接的状态(存在还是不存在),具体方法是什么?
加载更多回复(3)

111,106

社区成员

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

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

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