基于TCP的P2PSocket通信

heku518 2010-08-19 11:19:36
如果我把客户断的网线拔掉,
服务器端如何知道客户端已经断开了?

请各位高手们给个想法,
有想过有心跳包的方式,但是不知道怎么做、
能不能给个参考的代码?
也有试过直接调用sendTimeOut和receiveTimeOut
但是好像都没用处!

急,不懂的也帮我顶一顶,凡顶者皆有5分。
回答者依据帮助情况给分!谢谢啦!
送完为止
...全文
1108 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
LIMINLY520 2011-08-01
  • 打赏
  • 举报
回复
路过……
就学习一下。。。。
增长见识了
heku518 2010-08-20
  • 打赏
  • 举报
回复
就快有点头绪了~感谢facky904,以及在座各位的鼎力相助!
heku518 2010-08-20
  • 打赏
  • 举报
回复
facky904 18小时前 回复
我自己的做法是这样的,这是我自己写的函数
/// <summary>
/// KeepAlive心跳包
/// </summary>
/// <param name="sock"></param>
/// <param name="onOff">开启关闭检测,1开启,0关闭</param>
/// <param name="keepALiveDelay">检测前的等待时间</param>
/// <param name="keepALiveInterval">检测的时间间隔</param>
public void KeepAlive_Timer(Socket sock, int onOff, int keepALiveDelay, int keepALiveInterval)
{
try
{
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)onOff).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)keepALiveDelay).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)keepALiveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
sock.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
}
catch (Exception err)
{
throw new Exception(err.Message);
}

}

对于服务器端的Socket,在每次Accept到一个接入的Socket时,要对该Socket设置一次
我用的是异步的Accept,在回调函数里面设置Socket的KeepAlive
列:
private void OnConnectRequest(IAsyncResult ar)
{

Socket listener = (Socket)ar.AsyncState;
Socket client = new Socket(listener.EndAccept(ar), this);
KeepAlive(client,1, 15000, 5000);
//其他代码
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
}
fingternest 2010-08-20
  • 打赏
  • 举报
回复
帮顶一下,顺便看看高人的指点!
heku518 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 sp1234 的回复:]
引用 13 楼 heku518 的回复:
哎当初网络这部分就不应该交给其他人做,现在很费劲!但是又不想重新做~
要是你设计这部分,你怎么做?

能力清楚才好回答。
[/Quote]

呵呵,如果是我设计的话,其实我也不知道从何入手,但是,可以参考书籍,自己就对整个流程比较清楚,看别人写的代码很是费劲的,有时候都不知道那个函数是干什么的,为什么那样做!
wangyue4 2010-08-19
  • 打赏
  • 举报
回复
socket.Receive()函数返回0代表对方断开。
p2p需要打洞,但好像不是所有的路由器都支持tcp吧,我记得以前看过一本书说是只有70%支持。
应该用udp吧
facky904 2010-08-19
  • 打赏
  • 举报
回复
你所说的要检测出网线断开的情况,归根结底,就是物理链路的检测问题

在.Net中实现心跳包邮两种方法
1.自己用Socket写心跳包,自己写比较繁琐,复杂,容易出错,不建议
2.其实.Net的Socekt本身就提供了KeepAlive,利用Socket.IoControl函数设置KeepAlive,可以实现心跳包,详细的方法可以参考这篇文章http://blog.csdn.net/wzd24/archive/2007/10/12/1821360.aspx,这是我建议的方法

我最近也在做一个TCP相关的项目,利用第二种方法很好的解决了心跳包的问题

有兴趣的可以邮件相互讨论 jiajian_904@foxmail.com
heku518 2010-08-19
  • 打赏
  • 举报
回复
有没有人做过的,就给段有价值的代码。或者给个网址,里面有相关资料的。
cwaspnet 2010-08-19
  • 打赏
  • 举报
回复
socket没搞过
heku518 2010-08-19
  • 打赏
  • 举报
回复
纯理论的我也知道啊!关键是如何实现~再顶!
chengtao999 2010-08-19
  • 打赏
  • 举报
回复
超时罗,getlasterror等等
louti 2010-08-19
  • 打赏
  • 举报
回复
你去连接他 超过一定时间 连接不上 视为客户端关闭
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 heku518 的回复:]
哎当初网络这部分就不应该交给其他人做,现在很费劲!但是又不想重新做~[/Quote]
要是你设计这部分,你怎么做?

能力清楚才好回答。
lq465312483 2010-08-19
  • 打赏
  • 举报
回复
服务端可以先把客户端socket保存起来啊,然后定时向客户端发信息。如何一定时间客户端没有响应说明客户端断开咯啊!
jianuMan 2010-08-19
  • 打赏
  • 举报
回复
心跳就是 格一段时间 调用服务器 ClientOnLine 接口 服务器 更新客户端最后联系时间

并且清除超过多少时间 未联系的客户端id

facky904 2010-08-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 heku518 的回复:]
引用 7 楼 facky904 的回复:
你所说的要检测出网线断开的情况,归根结底,就是物理链路的检测问题

在.Net中实现心跳包邮两种方法
1.自己用Socket写心跳包,自己写比较繁琐,复杂,容易出错,不建议
2.其实.Net的Socekt本身就提供了KeepAlive,利用Socket.IoControl函数设置KeepAlive,可以实现心跳包,详细的方法可以参考这篇文章htt……
[/Quote]

171128203@qq.com
heku518 2010-08-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zhgroup 的回复:]
两种方式
第一种就是如果给客户端发送数据在指定时间内超时,可以认为客户端已断开连接,
第二种,客户端定时向服务端发送其在线消息,就像QQ似的;服务端根据客户端发送在线消息的最后时间来确定该客户端是否在线
[/Quote]
客户端发送数据在指定时间内超时,指定时间是多少,这个概念很模糊?
什么时候网络有可能出现阻塞,也认为客户端已经断开连接吗?
而且我的底层,也就是所谓的客户端其实就是一块电路板的芯片在处理!不是软件~实现起来也挺麻烦!

再者我用的是P2PSocket通信,总感觉这东西用起来特别麻烦。
一点都不熟悉这么个P2PSocket通信,哎当初网络这部分就不应该交给其他人做,现在很费劲!但是又不想重新做~
如若初见 2010-08-19
  • 打赏
  • 举报
回复
正在学习,但总感觉这东西很深奥
zhgroup 2010-08-19
  • 打赏
  • 举报
回复
两种方式
第一种就是如果给客户端发送数据在指定时间内超时,可以认为客户端已断开连接,
第二种,客户端定时向服务端发送其在线消息,就像QQ似的;服务端根据客户端发送在线消息的最后时间来确定该客户端是否在线
porschev 2010-08-19
  • 打赏
  • 举报
回复
没搞过。。。帮顶一下。。
加载更多回复(1)

110,524

社区成员

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

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

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