// ttt.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <winsock2.h> 
#include <windows.h> 
#include <stdio.h>#define   SENDOPTION   1   
#define   RECVOPTION   2  
#define PORT 5150 
#define DATA_BUFSIZE 8192 typedef struct 

   OVERLAPPED Overlapped; 
   WSABUF DataBuf; 
   CHAR Buffer[DATA_BUFSIZE]; 
   DWORD BytesSEND; 
   DWORD BytesRECV; 
   DWORD   Option; 
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA; 
typedef struct  

   SOCKET Socket; 
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA; 
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID); void main(void) 

   SOCKADDR_IN InternetAddr; 
   SOCKET Listen; 
   SOCKET Accept; 
   HANDLE CompletionPort; 
   SYSTEM_INFO SystemInfo; 
   LPPER_HANDLE_DATA PerHandleData; 
   LPPER_IO_OPERATION_DATA PerIoData; 
   int i; 
   DWORD RecvBytes; 
   DWORD Flags; 
   DWORD ThreadID; 
   WSADATA wsaData; 
   DWORD Ret;    if ((Ret = WSAStartup(0x0202, &wsaData)) != 0) 
   { 
      printf("WSAStartup failed with error %d\n", Ret); 
      return; 
   }    // Setup an I/O completion port.    if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL) 
   { 
      printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError()); 
      return; 
   }    // Determine how many processors are on the system.    GetSystemInfo(&SystemInfo);    // Create worker threads based on the number of processors available on the 
   // system. Create two worker threads for each processor.    for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2 + 2; i++) 
   { 
      HANDLE ThreadHandle;       // Create a server worker thread and pass the completion port to the thread.       if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort, 
         0, &ThreadID)) == NULL) 
      { 
         printf("CreateThread() failed with error %d\n", GetLastError()); 
         return; 
      }       // Close the thread handle 
      CloseHandle(ThreadHandle); 
   }    // Create a listening socket    if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 
      WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) 
   { 
      printf("WSASocket() failed with error %d\n", WSAGetLastError()); 
      return; 
   }     InternetAddr.sin_family = AF_INET; 
   InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
   InternetAddr.sin_port = htons(PORT);    if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR) 
   { 
      printf("bind() failed with error %d\n", WSAGetLastError()); 
      return; 
   }    // Prepare socket for listening    if (listen(Listen, 5) == SOCKET_ERROR) 
   { 
      printf("listen() failed with error %d\n", WSAGetLastError()); 
      return; 
   }    // Accept connections and assign to the completion port.    while(TRUE) 
   { 
      if ((Accept = WSAAccept(Listen, NULL, NULL, NULL, 0)) == SOCKET_ERROR) 
      { 
         printf("WSAAccept() failed with error %d\n", WSAGetLastError()); 
         return; 
      }       // Create a socket information structure to associate with the socket 
      if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,  
         sizeof(PER_HANDLE_DATA))) == NULL) 
      { 
         printf("GlobalAlloc() failed with error %d\n", GetLastError()); 
         return; 
      }       // Associate the accepted socket with the original completion port.       printf("Socket number %d connected\n", Accept); 
      PerHandleData->Socket = Accept;       if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData, 
         0) == NULL) 
      { 
         printf("CreateIoCompletionPort failed with error %d\n", GetLastError()); 
         return; 
      }       // Create per I/O socket information structure to associate with the  
      // WSARecv call below.       if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,          sizeof(PER_IO_OPERATION_DATA))) == NULL) 
      { 
         printf("GlobalAlloc() failed with error %d\n", GetLastError()); 
         return; 
      }       ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED)); 
      PerIoData->BytesSEND = 0; 
      PerIoData->BytesRECV = 0; 
      PerIoData->DataBuf.len = DATA_BUFSIZE; 
      PerIoData->DataBuf.buf = PerIoData->Buffer; 
  PerIoData->Option = RECVOPTION;
      Flags = 0; 
      if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, 
         &(PerIoData->Overlapped), NULL) == SOCKET_ERROR) 
      { 
         if (WSAGetLastError() != ERROR_IO_PENDING) 
         { 
            printf("WSARecv() failed with error %d\n", WSAGetLastError()); 
            return; 
         } 
      }
   } 
} DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID) 

HANDLE CompletionPort = (HANDLE) CompletionPortID; 
DWORD BytesTransferred; 
LPOVERLAPPED Overlapped; 
LPPER_HANDLE_DATA PerHandleData; 
LPPER_IO_OPERATION_DATA PerIoData; 
DWORD SendBytes, RecvBytes; 
DWORD Flags = 0; 
SendBytes = 0;
RecvBytes = 0;
while(TRUE) 

 
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, 
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0) 

printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError()); 
return 0; 

// First check to see if an error has occured on the socket and if so 
// then close the socket and cleanup the SOCKET_INFORMATION structure 
// associated with the socket.  if (BytesTransferred == 0) 

printf("Closing socket %d\n", PerHandleData->Socket);  closesocket(PerHandleData->Socket);
    delete PerIoData;
    delete PerHandleData;
continue;


if (PerIoData->Option = RECVOPTION)
{
printf ("Recv: %s\n", PerIoData->Buffer);

ZeroMemory(&(PerIoData->Overlapped),   sizeof(OVERLAPPED));   
strncpy(PerIoData->Buffer   ,"go away",20);   
PerIoData->DataBuf.len   =   DATA_BUFSIZE;   
PerIoData->DataBuf.buf   =   PerIoData->Buffer;   
PerIoData->Option = SENDOPTION;   
if   (WSASend (PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, Flags,   
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)   
{   
if   (WSAGetLastError()   !=   ERROR_IO_PENDING)   
{   
printf("WSASend()   failed   with   error   %d\n",   WSAGetLastError());   
return   0;   
}   
}  }
else if(PerIoData->Option == SENDOPTION)   
{   
printf("Send   SuccessFul\n");  
continue;   
} } 
}以上代码有问题吗?
WSASend  之后从没到过else if(PerIoData->Option == SENDOPTION 这里面来~~结果就是在
if (PerIoData->Option = RECVOPTION)
{
printf ("Recv: %s\n", PerIoData->Buffer);
printf也把发送的打印出来的,