求socket编程:心跳包,发送/接收稳定性的处理

pvlking 2010-12-08 04:53:32
关于“心跳包”的一些情况可以看下这个帖子:http://topic.csdn.net/u/20101014/08/e8edadc8-6e49-4e92-8bc3-cc7a12c4c0cf.html
简单的说下:我用的C/S结构。 C端有两个定时器:一个定时器10秒向S端发送一个检测信息,另一个每10秒累加一次变量 online++,当online >6时,就认为自己和S端的连接不通了,清除连接。(online变量的值当接收到S端发过来的检测信息就清零)。
S端同样有两个定时器:一个每10秒定时向C端发送检测信息,另一个每10秒累加变量online[n]++(有几个C端就有几个online),大于6是就认为和这个C端连接不通,清除连接。
出现的问题:程序挂着,不定时的出现C端接收不到S端的检测信息,或者S端接收不到C端的检测信息,6次后接判断掉线了。广域网的情况比局域网严重
我发送部分的代码:
OL msObj;
memset(&msObj,0,sizeof(OL));
strcpy(msObj.strName,m_csUserNameOrAddr);
msObj.iType=ONLINESTATION;
msObj.iSubType = 2;
int ret =theApp.m_skMainSocket.Send(&msObj,sizeof(msObj));
m_bsend =0;
if(ret == sizeof(OL))
{
m_bsend =1;//用来记录是否把内容发送到缓冲区
}
m_stime ++;//用来记录send执行的次数

我接收部分的代码:
unsigned char buf[10000];//无符号、有符号的有什么区别
iLen=Receive(buf,8,0);
int iLen1;
int iLen2;
iType=buf[0];
iSubType = buf[4];
MHD msContent1;
Message msContent;
OL msContent3;
if(buf[0]==BODY)//这里具有特殊性,其他地方不能这么写。
{
iLen1 = sizeof(MHD)-8;
iLen2 = sizeof(MHD)-8;
memset(&msContent1,0,sizeof(msContent1));
while(iLen1 > 0)
{
iLen = Receive(&buf[iLen2-iLen1+8], iLen1);
if (iLen > 0)
{
iLen1 = iLen1-iLen;
}
else
{
break;
}
}
memcpy(&msContent1,buf,sizeof(msContent1));
}
else if(buf[0]==ONLINESTATION)
{
iType=buf[0];
iSubType = buf[4];
iLen1 = sizeof(OL)-8;
iLen2 = sizeof(OL)-8;
memset(&msContent3,0,sizeof(msContent3));
while(iLen1 > 0)
{
iLen = Receive(&buf[iLen2-iLen1+8], iLen1);
if (iLen > 0)
{
iLen1 = iLen1-iLen;
}
else
{
break;
}
}
memcpy(&msContent3,buf,sizeof(msContent3));
}
else if(buf[0]==STATE)
{}
else
{
iLen1 = sizeof(Message)-8;
iLen2 = sizeof(Message)-8;
memset(&msContent,0,sizeof(msContent));
while(iLen1 > 0)
{
iLen = Receive(&buf[iLen2-iLen1+8], iLen1);
if (iLen > 0)
{
iLen1 = iLen1-iLen;
}
else
{
break;
}
}
memcpy(&msContent,buf,sizeof(msContent));
}

我不知道是不是我发送和接收处理的不好 ,造成的。

先总结下这几天测试的结果:程序都只是挂着,只有心跳包的交流,下面说的发送成功是send函数m_bsend =1:

基本上都是:C(S)端成功发送“检测信息”到缓冲区,但S(C)端没有接收到。 同时S(C)发送“检测信息”是成功的,C(S)端也能够接收到这个“检测信息”。PC的操作越频繁,问题也越频繁。
可惜的是,开3个C端的时候,没有出现 C1发送成功,S端接收不到的情况。不然能看看此时C2发送的信息 S端是不是能接收到。




下面是我这几天测试的结果记录:
1、环境:C-S在同一台PC上,PC的操作浏览网页,QQ。 结果:C端发送成功了86次,但S端只接收到检测信息81次,S端发送87次,C端接收到检测信息87次。 c端发送检测信息 S端没接收到,但S端发送检测信息,C端却接收到的。

2、环境:局域网3个PC,一台PC开S端和C端,其他两台开C端,PC操作挂机。 结果:当S端发送检测信息2433次时,一个C端接收不到了,但此时,这个C端发送給S端的检测信息S端是能收到的。6次后这个C端断开连接。 其他两个C端直到6662次还是正常。

等等等等。。。。。。
...全文
990 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
longren331100 2010-12-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 eyey1 的回复:]

引用 7 楼 visualeleven 的回复:
引用 3 楼 yihandrensunyong 的回复:
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到

TCP丢包很正常?正常吗????

很不正常.
[/Quote]
非常不正常
wangxialikenet 2010-12-09
  • 打赏
  • 举报
回复
不太明白,顶了
jackson35296 2010-12-09
  • 打赏
  • 举报
回复
搞什么心跳包啊,另起一个线程定时用select去查询socket的状态,无论是断网,断电或者是关闭了socket,select函数都会查出该套接字是error,具体原因用WSAGetLastError去判断。我就不明白了,非要整个心跳包干啥,TCP本来就是面向连接的,socket有任何变化,操作系统底层都会给予通知。再不行,把socket和一个完成端口绑定,用GetQueuedCompletionStatus去查询端口状态,有错误,有断网等,立刻就得到通知
pvlking 2010-12-09
  • 打赏
  • 举报
回复
最新情报:
我把心跳包去掉后,SOCKET连接还是会断的,我发文字信息接收不到了。 确实是连接不稳定。 为什么会断掉?广域网会比局域网断的频繁,链路上的数据多了也会比较频繁。
S端挂了两个C端,1个C端断了,还有个C端正常。

为了提高点压力:互相看这对方的视频,并且在录像。 (在局域网做的实验)

图像数据传输不是用的这个SOCKET的连接,直接从视频头拿的数据
手机写程序 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 visualeleven 的回复:]
引用 3 楼 yihandrensunyong 的回复:
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到

TCP丢包很正常?正常吗????
[/Quote]
很不正常.
pvlking 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 visualeleven 的回复:]
引用 3 楼 yihandrensunyong 的回复:
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到

TCP丢包很正常?正常吗????
[/Quote]
是我定时器,发送接收,什么的冲突了吗?
比如说:定时器1触发了 在执行代码的时候,定时器2也触发了:要发送数据,同时还有数据包传了过来。
pvlking 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wd2smile 的回复:]
是不是粘包问题呢,你检查下接受的数据大小是否一致,如果接受的数据包大小一样,就是粘包了,可以自己来拆!
TCP 怎么会丢包正常嘛 开玩喜!
[/Quote]

以前传BODY数据包的时候,基本上一次recv接收不完整的。 所以我在接收部分 我都用了WHILE循环:
直到接收到的长度和数据包包长一样 才进行下面的操作。
pvlking 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zzw820626 的回复:]
看你程序挺复杂,帮你顶一下把。
[/Quote]
不太复杂的:发送么就个send()。 m_bsend 的是我来记录这次发送是不是发送成功了(到缓冲区)。

接收部分么,因为有的数据发送的频率比较高,有的发送的比较少。我就分成了3个数据包。先接收8个字符来判断是什么类型的数据包,再接收后面的数据。 做测试的时候 其实就一个 检测信息的数据包在 发送。

wd2smile 2010-12-09
  • 打赏
  • 举报
回复
是不是粘包问题呢,你检查下接受的数据大小是否一致,如果接受的数据包大小一样,就是粘包了,可以自己来拆!
TCP 怎么会丢包正常嘛 开玩喜!
Eleven 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yihandrensunyong 的回复:]
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到
[/Quote]
TCP丢包很正常?正常吗????
zzw820626 2010-12-09
  • 打赏
  • 举报
回复
看你程序挺复杂,帮你顶一下把。
pvlking 2010-12-09
  • 打赏
  • 举报
回复
唉,先结贴了。 既然不是因为心跳包照成的断线,重新开个帖子了。
pvlking 2010-12-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 jackson35296 的回复:]
搞什么心跳包啊,另起一个线程定时用select去查询socket的状态,无论是断网,断电或者是关闭了socket,select函数都会查出该套接字是error,具体原因用WSAGetLastError去判断。我就不明白了,非要整个心跳包干啥,TCP本来就是面向连接的,socket有任何变化,操作系统底层都会给予通知。再不行,把socket和一个完成端口绑定,用GetQueuedCompletion……
[/Quote]

我去找点资料看看,能简单说明下怎么用不?
pvlking 2010-12-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yihandrensunyong 的回复:]
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到
[/Quote]

我觉得好像是连接上面的事,一开始接收不到就连续6次接收不到。没出现过,接收不到2次,又能接收到的情况
阻塞啊什么的~ 唉~难搞~
pvlking 2010-12-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jacklzw88 的回复:]
晕,都被你搞混了,不久一个心跳包么,有必要那么复杂嘛。。。
[/Quote]
心跳包不是 发送个检测信息来表示 在线么? 给点优化的思路呢? 我觉得我的COSKDET连接不稳定 还是怎么的。
yihandrensunyong 2010-12-08
  • 打赏
  • 举报
回复
TCP丢包很正常,可以提高C端发送的频率,同时延长S端认为断开的时间。别的方法暂时想不到
jacklzw88 2010-12-08
  • 打赏
  • 举报
回复
晕,都被你搞混了,不久一个心跳包么,有必要那么复杂嘛。。。
pvlking 2010-12-08
  • 打赏
  • 举报
回复
阻塞啊,非阻塞啊,不是太明白,没进行什么设置,就普通的socket连接。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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