服务端
struct PER_IO_DATA
{
SOCKET sClient;
char * buff;
int nLen;
OVERLAPPED overLap;
int nIOType;
};
struct PER_HANDLE_DATA
{
SOCKET sock;
sockaddr_in addr;
};DWORD WINAPI WorkThread(LPVOID lpParameter)
{ HANDLE hComplete=lpParameter;
PER_HANDLE_DATA* pHandle=NULL;
DWORD nLen=0;
PER_IO_DATA* pIO=NULL;
while(1)
{
BOOL bOK=::GetQueuedCompletionStatus(hComplete,&nLen,
                               (LPDWORD)&pHandle,(LPOVERLAPPED*)&pIO->overLap,INFINITE);
if(bOK)
{
if(pIO->nIOType==IO_ACCEPT)
{
printf("accept");
}
} }
return 0;
}
void main()
{ HANDLE m_hComplete=::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
SOCKET sockListen=::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=INADDR_ANY;
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);

::bind(sockListen,(sockaddr*)&addr,sizeof(sockaddr)); ::listen(sockListen,10);
// 将监听套节字关联到完成端口,注意,这里为它传递的CompletionKey为0
::CreateIoCompletionPort((HANDLE)sockListen, m_hComplete, (DWORD)0, 0); //投递5个链接请求
for(int i=0;i<5;i++)
{
PER_IO_DATA* pBuffer=(PER_IO_DATA *)::GlobalAlloc(GPTR,sizeof(PER_IO_DATA)+BUFF_SIZE);
pBuffer->buff=(char*)(pBuffer+1);
pBuffer->nIOType=IO_ACCEPT;
SOCKET sClient = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
::AcceptEx(sockListen, 
pBuffer->sClient,
pBuffer->buff, 
pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16, 
sizeof(sockaddr_in) + 16, 
&dwBytes, 
&pBuffer->overLap);
} DWORD nID=0;
::CreateThread(NULL,0,WorkThread,m_hComplete,0,&nID); // 创建事件对象,不让主程序退出
HANDLE hEvent = ::CreateEvent(NULL, FALSE, FALSE, "ShutdownEvent");
::WaitForSingleObject(hEvent, INFINITE);
}
客户端:
SOCKET m_sockListen=::socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
if(INVALID_SOCKET==::connect(m_sockListen,(sockaddr*)&addr,sizeof(sockaddr)))
{
printf("error"); }
客户端connect成功后,GetQueuedCompletionStatus(),还是阻塞

解决方案 »

  1.   

    你的意思是客户端连接后,工作线程中的GetQueueCompletionStatus()没有返回,阻塞在那里?
    -------------------------------------------------
    你的AcceptEx函数中的参数设置的是要求客户端连接后发送第一块数据,AcceptEx函数才会返回,这时GetQueueCompletionStatus()函数才会获取完成封包
      

  2.   

    创建socket后,在AcceptEx中等待连接到来,并且需要收取一块数据,不然得不到完成通知,GetQueueCompletionStatus自然没有返回
      

  3.   

    GetQueuedCompletionStatus FunctionAttempts to dequeue an I/O completion packet from the specified I/O completion port. If there is no completion packet queued, the function waits for a pending I/O operation associated with the completion port to complete.
      

  4.   

    你客户端连接后,有没有发送一段数据过来,否则get是不会返回的,你的accpetex中包含有这个,或者你不接收一段数据,可以参看msdn解释,