socket数据分包传送问题

yeekai 2006-09-19 04:38:19
用socket分包传输数据,只有第一个包能收到,后面的数据包都丢失了,但是在本机上同时运行server端和client端来分包传输数据却没有问题,请问这是怎么回事?以下是分包发送的代码。
SendMsg(BYTE* vIn,DWORD vLen)
{
WaitForSingleObject(m_hSendSema,INFINITE);

BYTE senddata[65535];
SocketMsgHead* head = (SocketMsgHead*)senddata;
head->ucQxFrameHead = 0x7E;
head->dwTotalLen = vLen;
head->wPacketNum = 1;
head->wPacketNO = 1;
head->wQxFrameLen = vLen;
if(vLen<=1024*60)
{
memcpy(senddata+sizeof(SocketMsgHead),vIn,vLen);
if(m_LinkState == TRUE)
{
if(Send(senddata,vLen+sizeof(SocketMsgHead)) == 0)
{
m_LinkState = FALSE;
}
}
}///
else //拆包发送
{
int i= 0;
head->wPacketNum = vLen/(1024*60) +1;
head->wQxFrameLen = 1024*60;
for(i=0;i<vLen/(1024*60);i++)
{
head->wPacketNO = i+1;
memcpy(senddata+sizeof(SocketMsgHead),vIn + i*1024*60,1024*60);
if(m_LinkState == TRUE)
{
if(Send(senddata,1024*60+sizeof(SocketMsgHead)) == 0)
{
m_LinkState = FALSE;
}
else
{
// Sleep(100);
continue;
}
}

} ///for
////下面发送最后一包

head->wPacketNO = i+1;
head->wQxFrameLen = vLen-i*1024*60;
memcpy(senddata+sizeof(SocketMsgHead),vIn + i*1024*60,vLen-i*1024*60);
Send(senddata,vLen-i*1024*60+sizeof(SocketMsgHead));
}
ReleaseSemaphore(m_hSendSema,1,NULL);
}
...全文
453 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jazy 2006-09-21
  • 打赏
  • 举报
回复
SOCKET s;
fd_set fdWrite = {0};
FD_SET(s, &fdWrite); // add socket s to the socket set
int ret = select(0, NULL, &fdWrite, NULL, NULL);
if (ret == SOCKET_ERROR)
{
// error condition ,socket not ready to write
}
if (ret > 0)
{
// At least 1 socket ready to write, in this case only s
}
softrain 2006-09-21
  • 打赏
  • 举报
回复
楼主应该是用了异步套接字.
异步发送当发送缓冲区被塞满之后就会返回错误.
你要判断每次发送多少,60K的数据第一次能发送完,下一次就未必,可能只发送一部分,因为每次发送都是把数据投递到发送缓冲区,缓冲区满了就返回ERROR.
所以你要判断发送出错的错误码,wsagetlasterror(),如果是wsaewouldblock,你就要sleep.
如果用了同步套接字,就不会出现这种问题.
mynamelj 2006-09-20
  • 打赏
  • 举报
回复
if(Send(senddata,1024*60+sizeof(SocketMsgHead))

int nRet= Send(senddata,1024*60+sizeof(SocketMsgHead);


可以看看到底发了多少字节出去了

int nLeft = vLen;
int nRet, nIndex = 0 ;
while (nLeft > 0)
{
nRet = Send(&senddata[nIndex], nLeft);
if(nRet == SOCKET_ERROR)
{
// Error..
}
nLeft -= nRet;
nIndex += nRet;
}
yeekai 2006-09-20
  • 打赏
  • 举报
回复
jazy,能说的详细一些吗?
jazy 2006-09-20
  • 打赏
  • 举报
回复
select一下
yeekai 2006-09-20
  • 打赏
  • 举报
回复
刚才我弄错了,发送第二个包的时候send返回socket_error,失败的原因似乎是socket没有准备好,请问有什么办法能够判断socket已经准备就绪了再进行数据发送吗?
chenyang80425 2006-09-20
  • 打赏
  • 举报
回复
//向客户端发送数据的函数。
int SendInfo(SOCKET m_fsocket,char *buffer,int len)
{
int cnt;
int rc;
cnt=len;
while(cnt>0)
{
rc=send(m_fsocket,buffer,cnt,0);
if(rc==SOCKET_ERROR)
{
AfxMessageBox("发送数据失败!");
return -1;
}
if(rc==0)
return len-cnt;
//发送完了一批数据后,缓冲区指针当然要向后移了。如果指定数量的数据已经发送完了,则
//bp就指向缓冲区的末尾了。
buffer+=rc;
//发送完了一批数据,则cnt(用来记录还没发送完的数据)的数值当然需要减去已经发送了的了。
cnt-=rc;
}
return len;
}
yeekai 2006-09-20
  • 打赏
  • 举报
回复
Send的返回值我检测过,是都发送成功了的。m_hSendSema只在这个函数中用到,应该不会造成死锁。是不是只要Send发送成功的话,OnReceive就能收到数据?
DentistryDoctor 2006-09-19
  • 打赏
  • 举报
回复
if(vLen<=1024*60) 60K做为分包大小?在网络中一次不一定能成功发送,需要检查send的返回值,以便得到到底发了多少数据。

hSendSema在这里有什么用?它有没有只要能造成死锁?

18,356

社区成员

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

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