客户端使用IOCP,开启工作线程后,如果不用等待函数HOLD住,工作线程就马上跳出。
#pragma once
#include "CMSocket.h"#define buffer_size 1024
int g_x=0;
typedef struct _PRE_HANDLE_DATA 
{
SOCKET s;
//PPRE_HANDLE_DATA pnext;
//sockaddr_in addr;//客户地址
}PRE_HANDLE_DATA,*PPRE_HANDLE_DATA;typedef struct _PRE_SOCKET_INFO
{
SOCKET socket;
struct _PRE_SOCKET_INFO *pnext;}PRE_SOCKET_INFO,*PPRE_SOCKET_INFO;PRE_SOCKET_INFO *g_socketinfo_line=NULL;typedef struct _PER_IO_DATA
{
OVERLAPPED overLapped;
char buf[buffer_size];
int nOperationtype;
WSABUF     wsabuf;

#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCPET 3
}PRE_IO_DATA,*PPRE_IO_DATA;PPRE_SOCKET_INFO PnewNode;
PPRE_IO_DATA pPreIoData;
class CIocpBA
{
public: CIocpBA()
{

m_hKillEvent=CreateEvent(NULL,true,false,NULL);
pPreIoData = (PPRE_IO_DATA)::GlobalAlloc(GPTR,sizeof(PRE_IO_DATA));
//PnewNode=(PRE_SOCKET_INFO*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PRE_SOCKET_INFO));
PnewNode=new PRE_SOCKET_INFO();
}
~CIocpBA(){}
void CreateComPort()
{
     hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
}

void Run()
{
HANDLE hThread;
CreateComPort();
hThread=::CreateThread(NULL,0,ClientThread,(LPVOID)hCompletion,0,0);
m_ihTimer=SetTimer(NULL,0,500,NULL);
InitClient();
}
static void PostIocpSend(SOCKET sockets,char *data=NULL,int datalen=0)
{
PPRE_IO_DATA pPreIoData = (PPRE_IO_DATA)::GlobalAlloc(GPTR,sizeof(PRE_IO_DATA)); pPreIoData->nOperationtype = OP_WRITE;
strcpy(pPreIoData->buf,"this is ok");
pPreIoData->wsabuf.buf=pPreIoData->buf;
pPreIoData->wsabuf.len=buffer_size;

ZeroMemory(&pPreIoData->overLapped,sizeof(OVERLAPPED)); DWORD Bytes;
DWORD Flags=0;
WSASend(sockets,&pPreIoData->wsabuf,1,&Bytes,Flags,&pPreIoData->overLapped,NULL);
} static void PostIocpRecv(SOCKET sockets)
{
PPRE_IO_DATA pPreIoData = (PPRE_IO_DATA)::GlobalAlloc(GPTR,sizeof(PRE_IO_DATA));
memset(pPreIoData->buf,0,buffer_size);
pPreIoData->wsabuf.buf=pPreIoData->buf;
pPreIoData->wsabuf.len=buffer_size;
pPreIoData->nOperationtype=OP_READ;
ZeroMemory(&pPreIoData->overLapped,sizeof(OVERLAPPED)); DWORD Bytes;
DWORD Flags=0;
WSARecv(sockets,&pPreIoData->wsabuf,1,&Bytes,&Flags,&pPreIoData->overLapped,NULL);
//pPreIoData->wsabuf.buf[Bytes+1]='\0';
//printf("%s\n\r",pPreIoData->wsabuf.buf);
//Sleep(1000);
}
static  DWORD WINAPI ClientThread(LPVOID lp)
{
HANDLE hCompletion = (HANDLE)lp; DWORD dwTrans;
PPRE_IO_DATA pPreIo;
PPRE_HANDLE_DATA pPreHandle;
while (true)
{
bool bok = ::GetQueuedCompletionStatus(hCompletion,&dwTrans,(unsigned long *)(&pPreHandle),(LPOVERLAPPED*)(&pPreIo),WSA_INFINITE); 
if(!bok)
{
::closesocket(pPreHandle->s);
::GlobalFree(pPreHandle);
::GlobalFree(pPreIo);
printf("getqueudcompletiontatatus errer");
continue;  }
/*if (dwTrans==0 && (pPreIo->nOperationtype==OP_READ||pPreIo->nOperationtype==OP_WRITE))
{
::closesocket(pPreHandle->s);
::GlobalFree(pPreHandle);
::GlobalFree(pPreIo);
continue;
}*/
InterlockedExchangeAdd(reinterpret_cast<long*>(&g_x),1);
DWORD dwflag=0;
switch(pPreIo->nOperationtype)
{
case OP_WRITE:
PostIocpSend(pPreHandle->s);
::GlobalFree(pPreIo);
Sleep(1000);
break; case OP_READ:
pPreIo->buf[dwTrans]='\0';
printf("%s\n",pPreIo->buf);
PostIocpRecv(pPreHandle->s);
::GlobalFree(pPreIo);
break;
} }
return 0;
} void UpdateServerSocket(CMSocket &CSocket)
{
//PRE_SOCKET_INFO *PnewNode=NULL;
//PnewNode=(PRE_SOCKET_INFO*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PRE_SOCKET_INFO)); PnewNode->socket=CSocket.m_socket;
PnewNode->pnext=NULL;
SocketWithCompletionPort(PnewNode); //PPRE_IO_DATA pPreIoData = (PPRE_IO_DATA)::GlobalAlloc(GPTR,sizeof(PRE_IO_DATA)); pPreIoData->nOperationtype = OP_READ;
ZeroMemory(&pPreIoData->overLapped,sizeof(OVERLAPPED));
PostQueuedCompletionStatus(hCompletion,0,(ULONG_PTR)PnewNode,(LPOVERLAPPED)&pPreIoData->overLapped);
PostIocpSend(PnewNode->socket);

if(g_socketinfo_line==NULL)g_socketinfo_line=PnewNode;
else
{
PnewNode->pnext=g_socketinfo_line;
g_socketinfo_line=PnewNode;
} //WaitForSingleObject(m_hKillEvent,INFINITE);
} void SocketWithCompletionPort(PRE_SOCKET_INFO *PNode) 
{
CreateIoCompletionPort(HANDLE(PNode->socket),hCompletion,DWORD(PNode),0); } void InitClient()
{
CMSocket socket;
strcpy(socket.ulAddress,"192.168.0.88");
socket.nPort=8801;
socket.initsocket();
socket.conn(); UpdateServerSocket(socket); // PostIocpSend(pPerHandle->s);

}
int m_ihTimer;
HANDLE hCompletion;
HANDLE m_hKillEvent;
};

解决方案 »

  1.   

    dwCreationFlags [in]
    The flags that control the creation of the thread.Value Meaning 
    0 The thread runs immediately after creation.
     
      

  2.   

    void Run()
    {
    HANDLE hThread;
    CreateComPort();
    hThread=::CreateThread(NULL,0,ClientThread,(LPVOID)hCompletion,0,0);
    m_ihTimer=SetTimer(NULL,0,500,NULL);
    InitClient();
    }
    二楼的说我线程有问题,不可能呀。直接运行不行吗?
      

  3.   

    看样子应该是主线程结束了,导致进程也结束
    那么子线程(工作线程)也没了
    所以hold住的是主线程
      

  4.   

    大家有没有用IOCP做客户端的范例,给予参考一下。我的客户端要一次性主动连接1000个服务端。
      

  5.   

    用IOCP做客户端,先说一下啊,没有源码,是 dll
    http://blog.csdn.net/robertbaker/article/details/8530507