在我们的考试系统中用到客户端和服务器之间的通信,服务器要时刻知道客户端的网络连接状态,当时我遇到这个问题的时候就没有在网上找到传说中的“心跳包”。只是凭自己心思随想写出了一个解决时下问题的算法。下面是客户端心跳包核心代码:
#region ++++++++++++++++++++客户端的感觉系统
//启动记时器
public void BeginTheTimer()
{
//th_UserLogin();
object myobject = (object)7; //这里只是要一个object类型数据,用它做为下面Timer的参数之一,其它没有什么意思
//暂时设定为1秒钟启动一次!
System.Threading.Timer t = new System.Threading.Timer(new System.Threading.TimerCallback(testTheNet), myobject, 1000, 1000);
}
//启动监视"已登录用户通信情况"的线程
public void testTheNet(object myobject)
{
//UserPassport up=new UserPassport();
Thread sendMyPulseThPro = new Thread(new ThreadStart(delegateSendMyPulse));
sendMyPulseThPro.Start();
}
/// <summary>
/// 每隔1秒就是要来做这些事情的
/// </summary>
public void delegateSendMyPulse()
{
loginServer lser = new loginServer();
Login l = new Login();
l.Id = lser.MyLogin.Id;
l.ClientTypeVersion = version;
l.RequestType = 3; //3是确认联接正常的一个信号(让服务知道它与服务器的联接是正常的)
loginServer lserver = new loginServer();
Thread thSendDat2 = new Thread(new ParameterizedThreadStart(lserver.delgSendDataMethod));//启动一个新线程去发送数据
thSendDat2.Start(l);
thSendDat2.IsBackground = true;
longinserver.MyLostTime += 1; //标记我已经发送出去一次数据了
if(longinserver.MyLostTime>=3) //如果外发了3次请求暗号后仍不见服务器的回应,则认为客户端已经与服务器断开联系了
{
//停止Timer
//告诉用户:“你已经与服务器失去联系了…………”
longinserver.Controls["txtShowMsg"].Text = "You have lost the connect!";
}
}
#endregion +++++++++++++++++++++客户端的感觉系统
服务器端代码如下:
#region +++++++++++++++++++++++服务器的感觉系统
//启动记时器
public void LoadTheTimer()
{
object o=(object)loginedCount++;
UserPassport up = new UserPassport();
//暂时设定为1秒钟启动一次!
System.Threading.Timer t = new System.Threading.Timer(new System.Threading.TimerCallback(watchTheLoginUser), o, 1000, 1000);
}
//启动监视"已登录用户通信情况"的线程
public void watchTheLoginUser(object o)
{
//UserPassport up=new UserPassport();
Thread checktheloginuser = new Thread(new ThreadStart(iAmAWatcher));
checktheloginuser.Start();
}
//真正做事的工人:这个工人的使命是每隔1秒钟后就查看一下登记薄registry里面有谁没有定时来向服务器报到了,如果出现谁三次检查都没有签到则除之名
public void iAmAWatcher()
{
this.txtLogin.Text += "@+";
int index = 0;
for (index = 0; index < loginedCount; index++)
{
if (myRegistry[index].alive==false&®istry[index].studentID!="")
{
lock(this)
{
myRegistry[index].no_check_in_count += 1; //坏(未到)记录增加一次
if (myRegistry[index].no_check_in_count >= 3)
{
//this.lblShowMsg.Text = "the student" + registry[index].studentID.ToString() + "is diaoxianle!";
this.txtLogin.Text += "88";
//标记该人已经与服务器失去连接了,因为他有连续3次的未到记录存在
registry[index].studentID = "";
registry[index].StudentName = "";
registry[index].StudentIP = "";
registry[index].status = 2; //掉线
}
}
}
}
}//定时检查在线人目前状态
#endregion +++++++++++++++++++服务器的感觉系统

posted on 2008-04-14 10:40
小胜 阅读(1981)
评论(14) 编辑 收藏
评论
| 2008-04-14 10:49
先研究一下这个东东
| 2008-04-14 11:14
收藏先,感谢楼主!
| 2008-04-14 13:54
呵呵.我来了.上面有些地方已经做过更改了........
| 2008-04-14 14:20
和我用的思想一样,但具体编码风格不同
| 2008-04-14 14:26
@nicye
以后有机会多多交流啊……呵呵……
| 2008-04-14 23:50
好,好,好东西啊。谁给我讲讲吧。看不懂啊。。。。。。。
| 2008-04-15 08:50

飞过
| 2008-04-15 10:41
有个问题请教一下楼主:
既然能够发送套接字给客户端,那客户端怎么会是死掉的呢?
难道是那种传说中的假死?
一般我以前就是检测sock对象的remoteendpoint对象,如果抛出异常,那么客户端就自己断开连接了
| 2008-04-15 12:18
感觉有点乱,不具有通用性。
| 2008-04-15 23:15
@PerfectDesign
应该是“假死”吧, 因为偶尔的一次发送不成功不能就断定它“死了”,所以多给几次机会,如果几次之后都是不通,就可以断定为失去了该连接端了。
| 2008-04-15 23:19
@Midapex Village
哈哈……是的,是有点乱,不好意思。
我在这里只是记录下我当时的思路,代码是从VS中粘过来的,宽度不对,当然排版看起来很些不清。对不住了! 我这两天正在奔波于找工作的事情中,怕是没有太多机会和你进一步交流了,有机会再联系吧。
| 2008-04-16 00:16
心跳的成本太高,以前做的一个联通的SGIP协议程序没有加上心跳。
不知道楼主是什么程序要用sock写呢?
sip?
| 2008-04-16 00:42
@PerfectDesign
是考试系统,学生要得到卷纸,答过一题服务就得记下考生的答案。数据交换较频繁。
| 2008-04-16 09:39
很奢侈啊!
.net做sock编程还是比较痛苦的
个人觉得用http应该可以应付了。