实现个远程注销功能 初学IOCP想试试 通信成功了 但接收数据好象收不到 点完注销按钮没反映,找不出什么毛病
烦劳高手慧眼识错 感激不尽服务端IOCP模型
#include <Winsock2.h>
#include <iostream.h>
#define BUFFER_SIZE 1024typedef struct _PER_HANDLE_DATA
{
   SOCKET s;
   sockaddr_in addr;
}PER_HANDLE_DATA,*PPER_HANDLE_DATA;typedef struct _PER_IO_DATA
{
OVERLAPPED ol;
char buf[BUFFER_SIZE];
int nOperationType;
#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3
}PER_IO_DATA,*PPER_IO_DATA;char *ID="PowerOff";
DWORD WINAPI ServerTheard(LPVOID lpParam);void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}


if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return; 
}
HANDLE hCompletion=CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
CreateThread(NULL,0,ServerTheard,(LPVOID)hCompletion,0,0);
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(12345);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

listen(sockSrv,5);

SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR); while(1)
{  
   
   SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
   PPER_HANDLE_DATA pHandle=(PPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PPER_HANDLE_DATA));
   pHandle->s=sockConn;
   memcpy(&pHandle->addr,&addrClient,len);
   CreateIoCompletionPort((HANDLE)pHandle->s,hCompletion,(DWORD)pHandle,0);
   
   PPER_IO_DATA pIo=(PPER_IO_DATA)GlobalAlloc(GPTR,sizeof(PPER_IO_DATA));
   pIo->nOperationType=OP_READ;
   
   WSABUF buf;
   buf.buf=pIo->buf;
   buf.len=BUFFER_SIZE;
   DWORD dwRecv;
   DWORD dwFlags=0;
   WSARecv(pHandle->s,&buf,1,&dwRecv,&dwFlags,&pIo->ol,NULL);
   
}
}DWORD WINAPI ServerTheard(LPVOID lpParam)
{
HANDLE hCompletion=(HANDLE)lpParam;
DWORD dwTrans;
PPER_HANDLE_DATA pHandle;
PPER_IO_DATA pIo; while (TRUE)
{
BOOL bOK=GetQueuedCompletionStatus(hCompletion,&dwTrans
,(LPDWORD)&pHandle,(LPOVERLAPPED*)&pIo,WSA_INFINITE);
                   if (!bOK)
{
closesocket(pHandle->s);
GlobalFree(pHandle);
GlobalFree(pIo);
continue;
        }
if (dwTrans==0&&(pIo->nOperationType==OP_READ||pIo->nOperationType==OP_WRITE))
{
closesocket(pHandle->s);
GlobalFree(pHandle);
GlobalFree(pIo);
continue;
}
switch(pIo->nOperationType)
{
case OP_READ:
{       
                        
if (ID==pIo->buf)
{  
                                 ExitWindowsEx(EWX_LOGOFF,0);  //就是实现个远程注销功能
                            }
WSABUF buf;
buf.buf=pIo->buf;
buf.len=BUFFER_SIZE;
DWORD dwRecv;
DWORD dwFlags=0;
WSARecv(pHandle->s,&buf,1,&dwRecv,&dwFlags,&pIo->ol,NULL);
}
break;
case OP_WRITE:
break;
case OP_ACCEPT:
break;

}
}
return 0;
}客户端:char *ID="PowerOff";
void CPowerOffDlg::OnBtnPoweroff() 
{
// TODO: Add your control notification handler code here
send(m_sock,ID,strlen(ID)+1,0);

}

解决方案 »

  1.   

    if (ID==pIo->buf) 
    不能用这种方式来比较吧,用下面的试试
    if(strcmp(ID,Pio->Buf))
      

  2.   

    错了,用下面的:
    if(strcmp(ID,Pio->Buf)==0)
      

  3.   

    BUFFER_SIZE 1024 
    不是没有收到数据,是你的BUFFER SIZE设置的太大了,IOCP需要把你这一块内存都填满了再返回.
    你只设置成8的大小,再试试看
      

  4.   

    if(strcmp(ID,Pio->Buf)==0) 改成
    if(strncmp(ID,pIo->buf,BUFFER_SIZE)==0)
      

  5.   


    case OP_READ:
    {       
                        cout<<pIo->buf<<endl;     //新加这段代码 按完按钮没有显示 看来数据没有传过来 哪位高人瞧瞧啊 迷茫啊!
    if(strncmp(ID,pIo->buf,BUFFER_SIZE)==0)
    {
                                                 ExitWindowsEx(EWX_LOGOFF,0);  
                                            }
    else
                                        cout<<"失败";
      

  6.   

    哦,明白了,GetQueuedCompletionStatus就相当于关联起来了,呵呵,
      

  7.   

    呵呵,GetQueuedCompletionStatus记得用两次啊,一次创建一次关联啊,别忘记了