代码:
class CClientContext  //To store and manage client related information
{
private:
     
     OVERLAPPED        *m_pol;
     WSABUF            *m_pwbuf;
     
     int               m_nTotalBytes;
     int               m_nSentBytes;
     
     SOCKET            m_Socket;  //accepted socket
     int               m_nOpCode; //will be used by the worker thread to decide what operation to perform
     char              m_szBuffer[MAX_BUFFER_LEN];
     
public:
     
     void SetOpCode(int n){m_nOpCode = n;}
     int GetOpCode(){return m_nOpCode;}
     void SetTotalBytes(int n){m_nTotalBytes = n;}
     int GetTotalBytes(){return m_nTotalBytes;}
     void SetSentBytes(int n){m_nSentBytes = n;}
     void IncrSentBytes(int n){m_nSentBytes += n;}
     int GetSentBytes() {return m_nSentBytes;}
     void SetSocket(SOCKET s){m_Socket = s;}
     SOCKET GetSocket(){return m_Socket;}
     void SetBuffer(char *szBuffer){strcpy(m_szBuffer, szBuffer);}
     void GetBuffer(char *szBuffer){strcpy(szBuffer, m_szBuffer);}
     void ZeroBuffer(){ZeroMemory(m_szBuffer, MAX_BUFFER_LEN);}
     void SetWSABUFLength(int nLength){m_pwbuf->len = nLength;}
     int GetWSABUFLength(){return m_pwbuf->len;}
     WSABUF* GetWSABUFPtr(){return m_pwbuf;}
     OVERLAPPED* GetOVERLAPPEDPtr(){return m_pol;}
     void ResetWSABUF()
   {ZeroBuffer();
       m_pwbuf->buf = m_szBuffer;
        m_pwbuf->len = MAX_BUFFER_LEN;
     }

     CClientContext()
     {
        m_pol = new OVERLAPPED;
        m_pwbuf = new WSABUF;
        ZeroMemory(m_pol, sizeof(OVERLAPPED));
        m_Socket =  SOCKET_ERROR;
        ZeroMemory(m_szBuffer, MAX_BUFFER_LEN);
        m_pwbuf->buf = m_szBuffer;  //这句话的意思是不是说 将m_szBuffer 指针给了buf 
       m_pwbuf->len = MAX_BUFFER_LEN;    //也就是说 实际上WSABUF里的数组指针指向的是m_szBuffer 实际接收的数据是 在m_szBuffer数组里 问题
        m_nOpCode = 0;
        m_nTotalBytes = 0;
        m_nSentBytes = 0;
     }
     

};
std::vector<CClientContext *> g_ClientContext;
bool InitializeIOCP();
bool Initialize();
void CleanUp();
void DeInitialize();
DWORD WINAPI AcceptThread(LPVOID lParam);
void AcceptConnection(SOCKET ListenSocket);
bool AssociateWithIOCP(CClientContext   *pClientContext);
DWORD WINAPI WorkerThread(LPVOID lpParam);
void WriteToConsole(char *szFormat, ...);
void AddToClientList(CClientContext   *pClientContext);
void RemoveFromClientListAndFreeMemory(CClientContext   *pClientContext);
void CleanClientList();
int GetNoOfProcessors();
#endif
int main(int argc, char *argv[])
{
   Initialize();
    SOCKET ListenSocket; 
   struct sockaddr_in ServerAddress;
    ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
     bind(ListenSocket, (struct sockaddr *) &ServerAddress, sizeof(ServerAddress));
      listen(ListenSocket,SOMAXCONN))
     g_hAcceptEvent = WSACreateEvent();
     WSAEventSelect(ListenSocket, g_hAcceptEvent, FD_ACCEPT);
      DWORD nThreadID;
     g_hAcceptThread = CreateThread(0, 0, AcceptThread, (void *)ListenSocket, 0, &nThreadID);
}

bool InitializeIOCP()
{
 g_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );

     DWORD nThreadID;
     for (int ii = 0; ii < g_nThreads; ii++)
     {
          g_phWorkerThreads[ii] = CreateThread(0, 0, WorkerThread, (void *)(ii+1), 0, &nThreadID);
     }
     
     return true;
}

DWORD WINAPI AcceptThread(LPVOID lParam)
{
     SOCKET ListenSocket = (SOCKET)lParam;
     
     WSANETWORKEVENTS WSAEvents;
     while(WAIT_OBJECT_0 != WaitForSingleObject(g_hShutdownEvent, 0))
     {
          if (WSA_WAIT_TIMEOUT != WSAWaitForMultipleEvents(1, &g_hAcceptEvent, FALSE, 0, FALSE))
          {
               void AcceptConnection(SOCKET ListenSocket)
{
     sockaddr_in ClientAddress;
     int nClientLength = sizeof(ClientAddress);
     SOCKET Socket = accept(ListenSocket, (sockaddr*)&ClientAddress, &nClientLength);
     CClientContext   *pClientContext  = new CClientContext;
     pClientContext->SetOpCode(OP_READ);    // 
     pClientContext->SetSocket(Socket);
     AddToClientList(pClientContext);  //这里是添加到列表里的 
     if (true == AssociateWithIOCP(pClientContext))  //请问这个关联操作会触发OP_READ 完成操作事件吗   问题1 ?????????
     { 
    pClientContext->SetOpCode(OP_WRITE);
      WSABUF *p_wbuf = pClientContext->GetWSABUFPtr();
      OVERLAPPED *p_ol = pClientContext->GetOVERLAPPEDPtr();  //我想这里的指针  得到指针 应该可以改变pClientContext 里的OVERLAPPED结构指针里的数据吧
      DWORD dwFlags = 0;  DWORD dwBytes = 0;
    //这里是接收一个字节 搞不懂为啥是一个字节 为啥 要接收难道我发送不行吗  问题2 ?????????
      int nBytesRecv = WSARecv(pClientContext->GetSocket(), p_wbuf, 1,&dwBytes, &dwFlags, p_ol, NULL);
  }
}

bool AssociateWithIOCP(CClientContext   *pClientContext)
{
     HANDLE hTemp = CreateIoCompletionPort((HANDLE)pClientContext->GetSocket(), g_hIOCompletionPort, (DWORD)pClientContext, 0);
 return true;
}

DWORD WINAPI WorkerThread(LPVOID lpParam)
{    
     int nThreadNo = (int)lpParam;
    void *lpContext = NULL;
     OVERLAPPED       *pOverlapped = NULL;
     CClientContext   *pClientContext = NULL;
     DWORD            dwBytesTransfered = 0;
     int nBytesRecv = 0;
     int nBytesSent = 0;
     DWORD    dwBytes = 0, dwFlags = 0;
     
     while (WAIT_OBJECT_0 != WaitForSingleObject(g_hShutdownEvent, 0))
     {
          BOOL bReturn = GetQueuedCompletionStatus(g_hIOCompletionPort,&dwBytesTransfered,(LPDWORD)&lpContext,&pOverlapped,INFINITE);
           pClientContext = (CClientContext *)lpContext;
         WSABUF *p_wbuf = pClientContext->GetWSABUFPtr();
         OVERLAPPED *p_ol = pClientContext->GetOVERLAPPEDPtr();
          switch (pClientContext->GetOpCode())
          {
          case OP_READ:
              pClientContext->IncrSentBytes(dwBytesTransfered);   //插入到m_nSentBytes 已经传输的字节数
               if(pClientContext->GetSentBytes() < pClientContext->GetTotalBytes())  //判断发送的数据是否小于总共要发送的数据 m_nTotalBytes
               {
                    pClientContext->SetOpCode(OP_READ);   //如果是 则设置标志为OP_READ  这里设置为 OP_READ 我想应该谁重复发送吧
                  p_wbuf->buf += pClientContext->GetSentBytes();   //向后移动 然后
                    p_wbuf->len = pClientContext->GetTotalBytes() - pClientContext->GetSentBytes();
                   dwFlags = 0;
                nBytesSent = WSASend(pClientContext->GetSocket(), p_wbuf, 1, &dwBytes, dwFlags, p_ol, NULL);
               }
               else  //到这里的意思是发送完毕吗  按道理这里应该也要设置为OP_READ 来实现重复接收啊 为啥是OP_WRITE
               {    
                    pClientContext->SetOpCode(OP_WRITE);  //如果发送的数据 大于总共要发送的 到这一步 设置开始接收数据 触发下一个事件 
              //为什么 没有没有关于WSARecv的 而且有也只有一个字节 难道接收只接收一个字节吗    问题 3?????????
          pClientContext->ResetWSABUF();  //清空WSABUF结构      
                    dwFlags = 0;
                   nBytesRecv = WSARecv(pClientContext->GetSocket(), p_wbuf, 1,&dwBytes, &dwFlags, p_ol, NULL);
               }
              break;
               
          case OP_WRITE:
               char szBuffer[MAX_BUFFER_LEN];
              pClientContext->GetBuffer(szBuffer);  //接收到的字节 怎么接收的没说啊 为啥只接收了一个字节 接受一个缓冲区为啥就能打印不继续接收 难道 继续接收应该设置下面那个标志为 OP_WRITE   //问题4??????
             WriteToConsole("\nThread %d: The following message was received: %s", nThreadNo, szBuffer);
              pClientContext->SetOpCode(OP_READ);   //继续接收 应该设置这个标志为OP_WRITE 为啥  
                  //设置发送的字节数为 0 总发送字节数为 接收到的字节数 
              pClientContext->SetTotalBytes(dwBytesTransfered);
              pClientContext->SetSentBytes(0);
                p_wbuf->len  = dwBytesTransfered;
               dwFlags = 0;
               nBytesSent = WSASend(pClientContext->GetSocket(), p_wbuf, 1,&dwBytes, dwFlags, p_ol, NULL);
}
有些东西我省略了方便大牛查看 帮忙解释下 啥云因