用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);
}
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);
}
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;
}
可以看看到底发了多少字节出去了int nLeft = vLen;
int nRet, nIndex = 0 ;
while (nLeft > 0)
{
nRet = Send(&senddata[nIndex], nLeft);
if(nRet == SOCKET_ERROR)
{
// Error..
}
nLeft -= nRet;
nIndex += nRet;
}
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
}
异步发送当发送缓冲区被塞满之后就会返回错误.
你要判断每次发送多少,60K的数据第一次能发送完,下一次就未必,可能只发送一部分,因为每次发送都是把数据投递到发送缓冲区,缓冲区满了就返回ERROR.
所以你要判断发送出错的错误码,wsagetlasterror(),如果是wsaewouldblock,你就要sleep.
如果用了同步套接字,就不会出现这种问题.