socket编程,连续调用send问题?

donkeydonkey 2009-08-31 03:30:07
昨天在写游戏程序的通信部分的时候,其中有一个位置出现了连续调用send函数来发送数据的情况…

send(...);//发送的是自定义的通信类型1的数据帧
send(...);//发送的是自定义的通信类型2的数据帧

在接收的时候,出现了错误!
后来经过了仔细的调试发现接收端只触发了一次接收的消息处理过程(用的是异步通信方式),而接收的数据长度是发送的
两个send函数总数据长度,内容也是两个的合并!!
我在两次放松中间加入

send(...);//发送的是自定义的通信类型1的数据帧
Sleep(5000);// 这样就能分开正确接收
send(...);//发送的是自定义的通信类型2的数据帧

我在网上查了一个下午,也没有找到合理的解决办法。开始以为是接收缓冲区接收覆盖,后来接收处加了一个变量锁来控制接收缓冲区,但是并没有解决,后来才发行时发送端的问题,出现了数据合并现象。

无奈之下请各位高手帮忙,
为什么出现数据的合并发送?
有没有办法分开发送?
有什么函数可以检查socket底层缓冲区的使用情况?(我想通过探测缓冲区情况来解决,只有当缓冲区没有使用的时候才启动下一次发送过程)
谢谢!
...全文
814 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyh_baoding 2009-09-01
  • 打赏
  • 举报
回复
发送的机制有问题
donkeydonkey 2009-08-31
  • 打赏
  • 举报
回复
哈哈谢谢各位!看了大家的回复,我已经明白了不少了!
  • 打赏
  • 举报
回复
貌似这个帖子可以解决粘包的问题
http://topic.csdn.net/u/20070303/20/ab2d7619-d9b8-4dfd-9cad-eba5a83bda63.html

select(MAX_CONNECTED_NO,&readfd,NULL,NULL,(struct timeval *)0)作用是设置关注readfd所包含的(句柄)是否有数据可读,你这里就只有sockfd一个。
FD_ISSET是一个宏,不是函数,作用就是检察一下现在是否有数据可读。

fd_set fdR;
FD_ZERO(&fdR);
FD_SET(socket, &fdR);
timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;

if(select(0, &fdR, NULL, NULL, &tv) > 0)
{
if (FD_ISSET(socket, &fdR))
{
。。。。
}
}
这样可能会影响效率
Conry 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 donkeydonkey 的回复:]
谢谢各位,可否在说的详细些?
有没有办法不让其粘包?
有什么函数可以检查socket底层缓冲区的使用情况?

[/Quote]
就tcp来说不粘包基本不可能,你正确的做法是如何拆包,组包
zhaohongbo83 2009-08-31
  • 打赏
  • 举报
回复
在包头部加一个长度,在每次取得时候判断包的长度!
oLINo 2009-08-31
  • 打赏
  • 举报
回复
没粘包做处理。
游戏网络处理,估计选择的是IOCP的方式。
看这里吧
http://www.codeproject.com/KB/IP/iocp_server_client.aspx
skybblue 2009-08-31
  • 打赏
  • 举报
回复
这个应该算是正常,因为Socket是以流的形式传输数据,就想文件流一样,当一个文件既有读又有写的时候,读是流出,写是流入,当你读的慢写的快的时候,那么文件中的未读取数据就有可能多次写入的数据,socket和这个原理类似,因此就有可能出现上述现象.为了避免出现这种现象,有两种办法,一种是包固定大小,你每次都读固定大小的数据,如果不够则继续读取剩余未读数据.另一种办法,就是在包中指定数据长度,根据长度区分每一个包大小,从而取出每个数据包.
雪影 2009-08-31
  • 打赏
  • 举报
回复
donkeydonkey 2009-08-31
  • 打赏
  • 举报
回复
谢谢各位,可否在说的详细些?
有没有办法不让其粘包?
有什么函数可以检查socket底层缓冲区的使用情况?
雪影 2009-08-31
  • 打赏
  • 举报
回复
这是正常的TCP粘包现象
出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据.
zzutligang 2009-08-31
  • 打赏
  • 举报
回复
用tcp通信,出现这种现象是很正常的。不但出现数据合并现象,还是出现数据拆分现象。
如果出现数据拆分,你还需使用组包的方式,来合并接受到的数据。

18,356

社区成员

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

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