18,356
社区成员
发帖
与我相关
我的任务
分享
//发送数据
extern "C"
WIN32API
int SendPacket(SOCKET hSock,char * sendBuf,int nLen)
{
DWORD offset=0,total=0;
DWORD Flags = 0,SendByts = 0;
LPPER_IO_OPERATION_DATA PerIoData = NULL;
IOCP_HEADER header;
DWORD dwRet = 0;
int nPreLen = 8192,nNowLen = 0;
int nFiledLen = sizeof(int);
if(sendBuf == NULL) return 0;
//获取原始发送缓冲区大小
getsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nPreLen,&nFiledLen);
//设置新的发送缓冲区大小为0
setsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nNowLen,sizeof(nNowLen));
//分配单句柄数据内存
PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA));
if(PerIoData == NULL)
{
TRACE("分配内存失败\n");
return -1;
}
//计算总包数
total=nLen / PACKET_SIZE;
if(nLen % PACKET_SIZE != 0)total++;
memset(&header,0,sizeof(header));
//设置包标识符
header.Identify = (UINT)InterlockedIncrement((LONG*)&g_cId);
//设置总包数
SET_PACKET_COUNT(header.Flag,total);
for(DWORD i=0; i<total; i++)
{
//设置包头属性,拷贝包头
header.Offset = offset;
(i==(total-1))?SET_PACKET_END(header.Flag):RESET_PACKET_END(header.Flag);
(i==(total-1))?SET_PACKET_LEN(header.Flag,nLen % PACKET_SIZE):SET_PACKET_LEN(header.Flag,PACKET_SIZE);
header.CheckSum = header.Flag + header.Offset + header.Identify;
memset(PerIoData->Buffer,0,DATA_BUFSIZE);
//拷贝头数据
memcpy(PerIoData->Buffer,&header,sizeof(IOCP_HEADER));
//拷贝发送数据
memcpy(PerIoData->Buffer + sizeof(IOCP_HEADER),sendBuf + offset,GET_PACKET_LEN(header.Flag));
//调整位移
offset = offset + GET_PACKET_LEN(header.Flag);
Flags = 0;
PerIoData->DataBuf.len = sizeof(IOCP_HEADER) + GET_PACKET_LEN(header.Flag);
PerIoData->DataBuf.buf = PerIoData->Buffer;
//发送数据
if(WSASend(hSock, &(PerIoData->DataBuf), 1, &SendByts, Flags, NULL, NULL) == SOCKET_ERROR)
{
//如果不是“设备忙”错误,则关闭SOCKET,并删除与之相关的结构
if (WSAGetLastError() != ERROR_IO_PENDING)
{
TRACE("WSASend failed with error [%ld]\n",WSAGetLastError());
break;
}
}
//统计发送字节数
dwRet = dwRet + SendByts;
}
GlobalFree(PerIoData);
//设置发送缓冲区设置成原始大小
setsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nPreLen,sizeof(nPreLen));
return dwRet;
}