关于完成端口连续发送丢包的问题

Smile_Tiger 2008-08-19 10:35:36
现象:
1.每次连续发送128byte的包,接受方却只能够收到第一个包
send(data,128);
send(data,128);
send(data,128);


2.间隔延迟足够的时间,接受方收到大包
send(data,128);
Sleep(1000);
send(data,128);
Sleep(1000);
send(data,128);
Sleep(1000);
3.发送语句片断
bool CIocpModeSvr::SendMsg(SOCKET sClient,const char * pData,unsigned long Length)
{
if(sClient==INVALID_SOCKET || pData==NULL || Length==0 || !IsStart)return false;

//申请操作键
PPER_IO_OPERATION_DATA PerIoData=(PPER_IO_OPERATION_DATA) \
GlobalAlloc(GPTR,
sizeof(PER_IO_OPERATION_DATA));

//准备缓冲
unsigned long Flag=0;
DWORD SendByte;
ZeroMemory(&(PerIoData->OverLapped),sizeof(OVERLAPPED));
memcpy(PerIoData->SendBuf,pData,Length);
PerIoData->SendDataBuf.buf=PerIoData->SendBuf;
PerIoData->SendDataBuf.len=Length;
PerIoData->OperType=SEND_POSTED;
int bRet=WSASend(sClient,
&(PerIoData->SendDataBuf),
1,
&SendByte,
Flag,
&(PerIoData->OverLapped),
NULL);
if(bRet==SOCKET_ERROR && GetLastError()!=WSA_IO_PENDING)
{
char LogStr[256];
_snprintf(LogStr,256,"WSASend With Error : %d",GetLastError());
WriteLogString(LogStr);
return false;
}
else return true;

return false;
}


想请教一下原因,以及解决方案
...全文
218 点赞 收藏 5
写回复
5 条回复
awjx 2008年08月29日
void DoData(SOCKET sClient,char* pData,DataLen,USER_INFO* pUser)
{
if( pUser->MsgLen == pUser->RecvLen)//刚好相等,直接处理
{
//完整的数据
}
else if(pUser->MsgLen > pUser->RecvLen)//接收到一个不完整的包,需要等待下一个包的到来。
{
//数据不完整,暂保存起来,等后面的数据到来
}
else //pUser->MsgLen < pUser->RecvLen,粘包了,需要分包处理。
{
//粘在一起,表示前半截数据是一个完整的包,处理该包后,后面的数据要进行递归
...
//递归
DoData(sClient,pData+iDeyLen,pUser->RecvLen,pUser);
}
}
回复 点赞
awjx 2008年08月29日
//思路代码

//组包分包,只有三种情况,需要分别处理,下面代码只是一个思路,或许很有帮助。
//MsgLen,消息结构体中定议的长度字段,比如消息结构如下:长度+消息体
//RecvLen,分几次接收后的消息的实际长度
//iDeyLen,粘包了,处理完前半截数据后,后半截数据进行递归

void DoData(SOCKET sClient,char* pData,DataLen,USER_INFO* pUser)
{
if( pUser->MsgLen == pUser->RecvLen)//刚好相等,直接处理
{
...
}
else if(pUser->MsgLen > pUser->RecvLen)//接收到一个不完整的包,需要等待下一个包的到来。
{
...
}
else //pUser->MsgLen < pUser->RecvLen,粘包了,需要分包处理。
{
...
//递归
DoData(sClient,pData+iDeyLen,pUser->RecvLen,pUser);
}
}
回复 点赞
Smile_Tiger 2008年08月26日
[Quote=引用 1 楼 awjx 的回复:]
这段代码好熟悉啊,我没猜错的话,应该是抄的吧?
TCP是流协议,没边界的,连续三次send(data,128),理论上,对方可能一次接收完成,也可能是大于三次才接收完成。但实际上,最大的可能是对方每次接收的长度是1460个字节。
关于粘包的现象,网上有很多讨论。(这个说法本身应该是错的,因为TCP本来就是流,无粘包分包之说)
[/Quote]

这段代码就是网络上杨飞写的源代码

[Quote=引用 2 楼 swxlion 的回复:]
连续三次调用send?而且是往同一地址同一端口发送逻辑上连续或相关的数据包?而且没有等待上一次发送的完成通知就直接发送第二次?
如果是这样的话,是有问题滴~~~~~
[/Quote]

请教一下如何操作?或者告诉我网络上比较好的代码我自己去看
回复 点赞
swxlion 2008年08月23日
连续三次调用send?而且是往同一地址同一端口发送逻辑上连续或相关的数据包?而且没有等待上一次发送的完成通知就直接发送第二次?
如果是这样的话,是有问题滴~~~~~
回复 点赞
awjx 2008年08月22日
这段代码好熟悉啊,我没猜错的话,应该是抄的吧?
TCP是流协议,没边界的,连续三次send(data,128),理论上,对方可能一次接收完成,也可能是大于三次才接收完成。但实际上,最大的可能是对方每次接收的长度是1460个字节。
关于粘包的现象,网上有很多讨论。(这个说法本身应该是错的,因为TCP本来就是流,无粘包分包之说)
回复 点赞
发动态
发帖子
通信技术
创建于2007-08-27

2785

社区成员

2.8w+

社区内容

通信技术相关讨论
社区公告
暂无公告