// 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也把发送的打印出来的,
少了个"="