关于TCP收发数据的疑问?

zpingy 2011-04-13 03:24:53
服务端我采用CAsyncSocket下的TCP模式收发数据,客户端我采用定时(200ms)发送28字节长度的数据,在接收端在OnReceive里面调用Receive方法接受数据,如果在接受数据的时候采取等待2ms再进行下一次接受,数据就完整,如果不sleep则偶尔会出现一次接受的数据长度超过28,请问原因?TCP数据传输不是安全的吗,难道会出现数据重复的情况?疑惑....
...全文
187 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhxingway 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zpingy 的回复:]
TCP的数据相当于是一个流,我读取了一部分,整个数据就往前走,新的数据进来填充,是这个意思吗?
[/Quote]

对,它还有一个缓冲区,发送端发送数据时会不断地填接收端的缓冲区,
zpingy 2011-04-17
  • 打赏
  • 举报
回复
TCP的数据相当于是一个流,我读取了一部分,整个数据就往前走,新的数据进来填充,是这个意思吗?
zpingy 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zk0233 的回复:]

把2ms的sleep去掉,对发送端和接收端的函数返回值做判断,对出错的时候进行处理
[/Quote]

具体怎么判断和处理?
zk0233 2011-04-14
  • 打赏
  • 举报
回复
把2ms的sleep去掉,对发送端和接收端的函数返回值做判断,对出错的时候进行处理
走走刀口 2011-04-14
  • 打赏
  • 举报
回复
涉及到粘包问题,使用多次发送和多次接收:

//发送数据
int SendHunk(SOCKET h,char *lpBuf,int nBufLen)
{
int nSend = -1 ;
int nSendAll = 0;

if( h != SOCKET_ERROR && lpBuf != NULL && nBufLen > 0 )
{
//循环发送,直到所有数据都发送完毕或出错就返回
do {

nSend = ::send(h, //已经连接的句柄
lpBuf+nSendAll, //跳过已经发送的数据
nBufLen-nSendAll, //计算剩余要发送的数据长度
0);

if( nSend > 0 )
nSendAll +=nSend;//累加已经成功发送的数据长度
else
break;

} while( nSendAll < nBufLen );
}

return nSendAll;
}

//接收数据
int RecvHunk(SOCKET h,char *lpBuf,int nBufLen,int nWillLen)
{
int nRecv = -1 ;
int nRecvAll = 0;

if( h != SOCKET_ERROR && lpBuf != NULL && nBufLen > 0 && nWillLen >0 && nBufLen >= nWillLen )
{
//循环接收,直到数据达到要接收的长度或出错就返回
do {

nRecv = ::recv(h, //已经连接的句柄
lpBuf+nRecvAll,//跳过已经接收的数据
nWillLen-nRecvAll,//计算剩余要接收的数据长度
0);
if( nRecv >0 )
nRecvAll = nRecv;//当前已经接收的长度
else
break;

} while( nRecvAll < nWillLen );
}

return nRecvAll;
}

yuzhonsha12 2011-04-14
  • 打赏
  • 举报
回复
你可以在接收端判断是否得到所需字节
wyx100 2011-04-14
  • 打赏
  • 举报
回复
每个数据包加一个包长度,或者每次都能计算出包长度,要不然总是粘一块,本来就是流
哈利路亚1874 2011-04-14
  • 打赏
  • 举报
回复
粘包情况,tcp/ip这样处理主要是为了提高网络利用效率
zpingy 2011-04-14
  • 打赏
  • 举报
回复
关于收发数据,还有个怪异的问题:我的电脑(比较老)测试不加Sleep可以正常收发,而新的电脑则一定要加sleep才能够处理,难道是因为处理太快的缘故?
羽飞 2011-04-14
  • 打赏
  • 举报
回复
每个数据包加一个包长度,或者每次都能计算出包长度,要不然总是粘一块,本来就是流
zpingy 2011-04-13
  • 打赏
  • 举报
回复
循环接受也没有问题,但是为啥接受数据时要等待一会儿就没有问题,如果一直循环接受数据就有问题呢?
Eleven 2011-04-13
  • 打赏
  • 举报
回复
同意ls大牛的,send和recv不是一一对应,send一次就recv一次,有可能send多次,然后recv一次就全部接收完成
cnzdgs 2011-04-13
  • 打赏
  • 举报
回复
TCP的发送和接收不是一一对应的,一次发送的数据可能需要多次接受才能收齐,多次发送的数据也可能一次收到。如果你想每次接收28字节数据,可以指定接收缓冲长度为28,这样就不会接收下一次发送的数据。另外还要根据函数的返回值来判断数据是否收全,如果只接收到一部分数据,要自己调整接收缓冲的指针和大小,继续接受后面的数据,直到收全位置。
killalarm 2011-04-13
  • 打赏
  • 举报
回复
要过滤掉 返回值=-1的情况,同时提醒你 要防止封包粘连

18,356

社区成员

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

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