主要用到的是WSAEventSelect模型
下面是一個簡單的示例代碼:
//控制箱開機
char *pCmd = "ONCP\r\n";
SOCKET sck=socket(PF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET ==sck)
ATLASSERT(0);
WSAEVENT hEvent = WSACreateEvent();
WSAEventSelect(sck,hEvent,FD_READ|FD_CONNECT);
struct sockaddr_in to;
to.sin_family=AF_INET;
to.sin_port=htons(SOCKET_POWERPORT);
to.sin_addr.s_addr=htonl(pconfig->dwIP);
try
{
WSAConnect(sck,(struct sockaddr*)&to,sizeof(to),NULL,NULL,NULL,NULL);
int nTry=10;
int ret=0;
int err=-1;
BYTE buffer[1024]={0};
int i=0;
for(i=0;i<30;i++)
{
if(WSAWaitForMultipleEvents(1,&hEvent,0,100,0)!=WSA_WAIT_EVENT_0)
{
err = -1;
}
else
{
WSANETWORKEVENTS events;
WSAEnumNetworkEvents(sck,hEvent,&events);
if( (events.lNetworkEvents | FD_CONNECT)==0 || events.iErrorCode[4]!=0)
{
err = -1;
}
else
err=0;
}
if(err==0) break;
Sleep(100);
}
if (err != 0)
{
//錯誤
*bstrMsg = SysAllocString(L"連接配接控制器失敗,請檢查控制器位址配置是否正确");
throw(1);
}
else
{
while(--nTry)
{
if(nTry<9)
Sleep(1000);
ret=send(sck,(const char*)pCmd, strlen(pCmd),0);
if( ret!=strlen(pCmd) )
{
*bstrMsg = SysAllocString(L"錯誤:發送資料失敗");
throw(5);
}
//接收傳回資料
for(i=0;i<30;i++)
{
ret=0;
ret=recv(sck, (char*)buffer, 1023, 0);
if(ret > 0)
break;
Sleep(100);
}
//容錯M61E
//if(ret==1)
if(ret>0)
{
if( buffer[0]==0)
{
*lSuccess= TRUE;
throw(0);
}
continue;
}
else
{
continue;
}
}//end while(nTry--)
}
if(ret>0)
{
if( buffer[0]==1)
{
*bstrMsg = SysAllocString(L"錯誤:開啟計算機失敗,請等待3分鐘後再進行操作");
throw(2);
}
else if( buffer[0]==2)
{
*bstrMsg = SysAllocString(L"錯誤:計算機已開啟");
throw(3);
}
else if( buffer[0]==3)
{
*bstrMsg = SysAllocString(L"錯誤:正在開機過程中");
throw(4);
}
else
{
OutputDebugString("接收開機指令傳回不符合協定");
*bstrMsg = SysAllocString(L"接收開機指令傳回不符合協定");
}
}
else
{
OutputDebugString("接收開機指令失敗:指令無傳回");
*bstrMsg = SysAllocString(L"接收開機指令失敗:指令無傳回");
throw(5);
}
}
catch(int err)
{
if(sck!=INVALID_SOCKET)
{
closesocket(sck);
}
sck=INVALID_SOCKET;
if(err)
{
*lSuccess= FALSE;
return S_FALSE;
}
else
{
*lSuccess= TRUE;
return S_OK;
}
}