您的位置:首页 > 大数据 > 人工智能

ECHOSRV.C中的main()设立一个 I/O completion port

2015-07-25 21:08 537 查看






#include<Windows.h>

int main(int argc, char* argv[])

{

SOCKET listener;

SOCKET newsocket;

WSADATA WsaData;

struct sockaddr_in serverAddress;

struct sockaddr_in clientAddress;

int clientAddressLength;

int err;

CheckOsVersion();

err = WSAStartup(0x0101, &WsaData);

if (err == SOCKET_ERROR)

{

FatalError("WSAStartup Failed");

return EXIT_FAILURE;

}

/*open a tcp socket connection to the server by d

default,a socket is alays opened for ouverlapped

I/O.DO NOT attach this socket (listener) to the

I/O completion port!*/

listener = socket(AF_INET, SOCK_STREAM, 0);

if (listener < 0)

{

FatalError("socket() failed");

return EXIT_FAILURE;

}

/*Bind our local address */

memset(&serverAddress, 0, sizeof(serverAddress));

serverAddress.sin_family = AF_INET;

serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);

serverAddress.sin_port = htons(SERV_TCP_PORT);

err = bind(listener, (struct sockaddr*)&serverAddress,

sizeof(serverAddress));

if (err < 0)

FatalError("bind() failed");

ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

if (ghCompletionPort == NULL)

{

FatalError("CreateIoCompletionPort() failed");

}

CreateWorkerThreads();

listen(listener, 5);

fprintf(stderr, "Echo Server with I/O Completion Ports\n");

fprintf(stderr, "Running on TCP port %d\n", SERV_TCP_PORT);

fprintf(stderr, "\n Press Ctrl+C to stop the server\n");

//loop forever accepting requests new connections and starting

// reading from them.

for (;;)

{

struct ContextKey *pKey;

clientAddressLength = sizeof(clientAddress);

newsocket = accept(listener, (struct sockaddr*) &clientAddress,

&clientAddressLength);

if (newsocket < 0)

{

FatalError("accept() Failed");

return EXIT_FAILURE;

}

/*Create acontext key and initialize it.

calloc with zero the buffer*/

pKey = calloc(1, sizeof(struct ContextKey));

pKey->sock = newsocket;

pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

/*Set the event for writing so that packets will

not be sent to hte completion port when a write finishes.*/

pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1);

//Associate the socket with the completion port

CreateIoCompletionPort((HANDLE)newsocket, ghCompletionPort, (DWORD)pKey, 0);

//kick off the first read

IssueRead(pKey);

}

return 0;

}

#include<Windows.h>

int main(int argc, char* argv[])

{

SOCKET listener;

SOCKET newsocket;

WSADATA WsaData;

struct sockaddr_in serverAddress;

struct sockaddr_in clientAddress;

int clientAddressLength;

int err;

CheckOsVersion();

err = WSAStartup(0x0101, &WsaData);

if (err == SOCKET_ERROR)

{

FatalError("WSAStartup Failed");

return EXIT_FAILURE;

}

/*open a tcp socket connection to the server by d

default,a socket is alays opened for ouverlapped

I/O.DO NOT attach this socket (listener) to the

I/O completion port!*/

listener = socket(AF_INET, SOCK_STREAM, 0);

if (listener < 0)

{

FatalError("socket() failed");

return EXIT_FAILURE;

}

/*Bind our local address */

memset(&serverAddress, 0, sizeof(serverAddress));

serverAddress.sin_family = AF_INET;

serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);

serverAddress.sin_port = htons(SERV_TCP_PORT);

err = bind(listener, (struct sockaddr*)&serverAddress,

sizeof(serverAddress));

if (err < 0)

FatalError("bind() failed");

ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

if (ghCompletionPort == NULL)

{

FatalError("CreateIoCompletionPort() failed");

}

CreateWorkerThreads();

listen(listener, 5);

fprintf(stderr, "Echo Server with I/O Completion Ports\n");

fprintf(stderr, "Running on TCP port %d\n", SERV_TCP_PORT);

fprintf(stderr, "\n Press Ctrl+C to stop the server\n");

//loop forever accepting requests new connections and starting

// reading from them.

for (;;)

{

struct ContextKey *pKey;

clientAddressLength = sizeof(clientAddress);

newsocket = accept(listener, (struct sockaddr*) &clientAddress,

&clientAddressLength);

if (newsocket < 0)

{

FatalError("accept() Failed");

return EXIT_FAILURE;

}

/*Create acontext key and initialize it.

calloc with zero the buffer*/

pKey = calloc(1, sizeof(struct ContextKey));

pKey->sock = newsocket;

pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

/*Set the event for writing so that packets will

not be sent to hte completion port when a write finishes.*/

pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1);

//Associate the socket with the completion port

CreateIoCompletionPort((HANDLE)newsocket, ghCompletionPort, (DWORD)pKey, 0);

//kick off the first read

IssueRead(pKey);

}

return 0;

}




ECHOSRV.C中的CreateWorkerThreads()

void CreateWorkerThreads()

{

SYSTEM_INFO sysinfo;

DWORD dwThreadId;

DWORD dwThreads;

DWORD i;

GetSystemInfo(&sysinfo);

dwThreads = sysinfo.dwNumberOfProcessors * 2 + 2;

for (i = 0; i < dwThreads; i++)

{

HANDLE hThread;

hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);

CloseHandle(hThread);

}

}



DWORD WINAPI ThreadFunc(LPVOID pVoid)

{

BOOL bResult;

DWORD dwNumRead;

struct ContextKey *pCntx;

LPOVERLAPPED lpOverlapped;

UNREFERENCED_PARAMETER(pVoid);

/*Loop forever on getting packets from

the I/O completion port*/

for (;;)

{

bResult = GetQueuedCompletionStatus(

ghCompletionPort, &dwNumRead,

&(DWORD)pCntx, &lpOverlapped, INFINITE);

if (bResult == FALSE && lpOverlapped == NULL)

{

FatalError("ThreadFunc -Illegal call to GetQueuedCompletionStatus");

}

else if (bResult == FALSE && lpOverlapped != NULL)

{

//This happens occasionally instead of

//end-of-file,Not sure why.

closesocket(pCntx->sock);

free(pCntx);

fprintf(stderr, "ThreadFunc - I/O operation falied \n");

}

else if (dwNumRead == 0)

{

closesocket(pCntx->sock);

free(pContx);

fprintf(stderr, "ThreadFunc - End of file.\n");

}

//Got a valid data block!

//Save the data to our buffer and write it

//all back out (echo it) if we have see a \n

else

{

//Figure out where in the buffer to save the character

char* pch = &pCntx->OutBuffer[pCntx->nOutBufIndex++];

*pch++ = pCntx->InBuffer[0];

*pch = '\0';

if (pCntx->InBuffer[0] == '\n')

{

WriteFile((HANDLE)(pCntx->sock),

pCntx->OutBuffer, pCntx->nOutBufIndex,

&pCntx->dwWritten, &pCntx->ovOut);

pCntx->nOutBufIndex = 0;

fprintf(stderr, "Echo on socket %x.\n",pCntx->sock);

}

//start a new read

IssueRead(pCntx);

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: