70,021
社区成员




/*-------------------------------------------------------------------
SOCKETROUTE.C——阻塞模式下使用的常用子程序
(c)by 浅墨浓香,2015.6.25
---------------------------------------------------------------------*/
#include <windows.h>
#include "Message.h"
#include "SocketRoute.h"
#pragma comment(lib,"Ws2_32.lib")
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 在规定的时间内等待数据到达
// 输入:dwTime = 需要等待的时间(微秒)
// 返回值:0 ——超时而返回
// SOCKET_ERROR ——出错而返回
// X(x>0) ——就绪的套接字数量
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int WaitData(SOCKET sock, DWORD dwTime)
{
FD_SET fds;
TIMEVAL tv;
fds.fd_count = 1;
fds.fd_array[0] = sock;
tv.tv_sec = 0;
tv.tv_usec = dwTime;
return select(0, &fds, NULL, NULL, &tv);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 接收规定字节的数据,如果缓冲区中的数据不够则等待
// 返回:FALSE,连接中断或发生错误
// TRUE,成功
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BOOL RecvData(SOCKET sock, char* pBuffer, int nBytes)
{
int nStartTime;
int nRet,nRecv;
nStartTime = GetTickCount();
nRecv = 0;
while ((GetTickCount()-nStartTime)<10*1000) //查看是否超时
{
nRet = WaitData(sock, 100 * 1000); //等待数据100ms
if (SOCKET_ERROR == nRet) //连接错误
return FALSE;
if (0 == nRet) //超时
break;
do
{
//接收数据,直至收完指定的字节数
nRecv += recv(sock, pBuffer + nRecv, nBytes - nRecv, 0);
if (nRecv == SOCKET_ERROR || nRecv == 0)
return FALSE;
if (nRecv == nBytes)
return TRUE;
} while (nRecv < nBytes);
}
return TRUE;
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 接收一个符合规范的数据包
// 参数: pBuffer用来接收数据的缓冲区
// nBytes 数据区最大的空间
// 返回: FALSE——失败
// TRUE ——成功
//注意:这里的nBytes不要指要接收的字节数,只是用来判断缓冲区是否只够大
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BOOL RecvPacket(SOCKET sock, char* pBuffer, int nBytes)
{
MSGSTRUCT* pMsgStruct;
int iRet;
pMsgStruct = (MSGSTRUCT*)pBuffer;
//接收数据包头部并检测数据是否正常
iRet = RecvData(sock, pBuffer, sizeof(MSGHEAD));
if (iRet) //如果成功接收数据
{
if (pMsgStruct->MsgHead.cbSize <= sizeof(MSGHEAD) ||
pMsgStruct->MsgHead.cbSize > nBytes)
return FALSE;
//接收余下的数据
iRet = RecvData(sock, pBuffer + sizeof(MSGHEAD), pMsgStruct->MsgHead.cbSize - sizeof(MSGHEAD));
}
return iRet;
}