18,356
社区成员
发帖
与我相关
我的任务
分享
typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char Buffer[MAX_BUFFER_SIZE];
DWORD BytesSend;
DWORD BytesRecv;
DWORD BytesLength;
DWORD BytesPin;
DWORD BytesFrom;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;
typedef struct _PER_HANDLE_DATA
{
SOCKET Socket;
SOCKADDR_IN addressinfo;
char parameters[256];
HANDLE g_pUser;
HANDLE g_pServer;
DOUBLE RecentTime;
LPPER_IO_OPERATION_DATA PerIoData;
LPPER_IO_OPERATION_DATA wPerIoData;
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;
PER_HANDLE_DATA中,PerIoData表示接收的IO,wPerIoData表示发送的IO。MAX_BUFFER_SIZE为8192。我发送的思路是,在我自定义的INetUser接口中,添加了PostMessage方法,该方法一般在服务器接收数据线程里面收到数据包后调用。PostMessage的思路是:在NetUser组件对象中,创建包队列,PostMessage将包按8192字节划分子包,按顺序添加至队列中,如果开始队列为空,将队列第一个包取出,使用WSASend发送。在在服务器接收数据线程,处理发送消息。如果当前包没有发完,继续WSASend投递,否则调用NetUser组件对象的SendNextPackage继续下一个包的投递。
代码如下:
void CNetUser::SendNextPackage()
{
//DWORD dwRet=WaitForSingleObject(m_hux,INFINITE);
//if(dwRet==WAIT_FAILED) return;
if(bClosed!=0) return;
WaitForSingleObject(m_sendEvent,INFINITE);
if(sendingPackage.GetSize()==0)
{
SetEvent(m_sendEvent);
//SetEvent(m_hux);
return;
}
sendingPackage.GetAt(0)->Release();
sendingPackage.RemoveAt(0);
if(sendingPackage.GetSize()==0)
{
SetEvent(m_sendEvent);
//SetEvent(m_hux);
return;
}
IDataPackage*subPack=sendingPackage.GetAt(0);
LONG length;
subPack->get_CurrentPackageSize(&length);
length+=PACKAGE_HEADER;
OLE_HANDLE pin;
subPack->GetStreamPtr(&pin);
BYTE*bbuff=(BYTE*)pin;
char*buff=(char*)bbuff;
memcpy(lpHandleData->wPerIoData->Buffer,buff,length);
lpHandleData->wPerIoData->BytesSend=length;
lpHandleData->wPerIoData->DataBuf.buf=lpHandleData->wPerIoData->Buffer;
lpHandleData->wPerIoData->DataBuf.len=length;
DWORD dwSend;
DWORD Flags=0;
int len=0;
ZeroMemory(&(lpHandleData->wPerIoData->Overlapped),sizeof(OVERLAPPED));
WSASend(lpHandleData->Socket, &lpHandleData->wPerIoData->DataBuf, 1, &dwSend, Flags, &lpHandleData->wPerIoData->Overlapped, NULL);
SetEvent(m_sendEvent);
//SetEvent(m_hux);
}
STDMETHODIMP CNetUser::PostMessage(IDataPackage*pdr,DataPackageCoderType type,VARIANT_BOOL*pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
*pVal=VARIANT_FALSE;
WaitForSingleObject(m_sendEvent,INFINITE);
if(lpHandleData==NULL)
{
SetEvent(m_sendEvent);
return S_OK;
}
IDataPackageSender*pSender;
::CoCreateInstance(CLSID_DataPackageSender,NULL,CLSCTX_INPROC_SERVER,IID_IDataPackageSender,(void**)&pSender);
pSender->put_DataPackageEncodeType(type);
VARIANT_BOOL IsOk;
pSender->SetSendingDataPackage(pdr,&IsOk);
if(!IsOk)
{
pSender->Release();
SetEvent(m_sendEvent);
return S_OK;
}
LONG oldSize=sendingPackage.GetSize();
IDataPackage*subPack;
while(true)
{
pSender->GetNextPackage(&subPack);
if(subPack==NULL) break;
sendingPackage.Add(subPack);
}
pSender->Release();
if((oldSize==0)&&(sendingPackage.GetSize()>0))
{
subPack=sendingPackage.GetAt(0);
LONG length;
subPack->get_CurrentPackageSize(&length);
length+=PACKAGE_HEADER;
OLE_HANDLE pin;
subPack->GetStreamPtr(&pin);
BYTE*bbuff=(BYTE*)pin;
char*buff=(char*)bbuff;
memcpy(lpHandleData->wPerIoData->Buffer,buff,length);
lpHandleData->wPerIoData->BytesSend=length;
lpHandleData->wPerIoData->DataBuf.buf=lpHandleData->wPerIoData->Buffer;
lpHandleData->wPerIoData->DataBuf.len=length;
DWORD dwSend;
DWORD Flags=0;
int len=0;
ZeroMemory(&(lpHandleData->wPerIoData->Overlapped),sizeof(OVERLAPPED));
WSASend(lpHandleData->Socket, &lpHandleData->wPerIoData->DataBuf, 1, &dwSend, Flags, &lpHandleData->wPerIoData->Overlapped, NULL);
}
SetEvent(m_sendEvent);
*pVal=VARIANT_TRUE;
return S_OK;
}