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

#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;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-24 08:58:15

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

XCODE中使用Main.Storyboard拉入控件并实现事件(Swift语言)

如何在XCODE中的Main.Storyboard内拉入控件并实现一个简单的效果呢?本人由于刚接触Swift语言不久,对于IDE的操作还是很生疏,不懂了就在网上参考了网上前辈们的文章.以下我将演示如何用Swift语言配合Main.Storyboard演示一个小例子,对于新建一个SingleView Application在这里就不多说了. 创建好的应用程序已经自动创建好了一个和Main.Storyboard连接好的ViewController. 接下来我们在Main.Storyboard中的Vi

Java中的main()方法详解

在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等. 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这个例子说明Java类中main()方法的奥秘,程序的代码如下: 1 /** 2 * Java中的main()方法

基于中序遍历找到一个结点的后继结点

题目: 基于中序遍历找到一个结点的后继结点. 分析: 首先明白中序遍历,顺序为:左--->根----->右 如果当前结点为p. 有两种情况: 1.当p有右子树时,那么其右子树的最左结点即为所求: 2.当p没有右子树时.有以下两种情况: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hkamo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center"

java 常见的几种类型范围说明,char 型变量中能不能存贮一个中文汉字

package com.yuan.test; public class Autogrew { public static void main(String[] args) {  // 保存 short 可取的最大值的常量,最大值为 215-1.(32 767)   // 保存 short 可取的最小值的常量,最小值为 -215.(-32 768)      short s1=11278;      s1+=1;      //s1=s1+1;//报错 自动会转换成int 类型      Syst

转:C#中Undo/Redo的一个简易实现

一个比较常见的改进用户体验的方案是用Redo/Undo来取代确认对话框,由于这个功能比较常用,本文简单的给了一个在C#中通过Command模式实现Redo/Undo方案的例子,以供后续查询. class Program { static void Main(string[] args) { var cmds = new CommandManager(); while (true) { var key = Console.ReadKey(true); if (key.KeyChar >= '0'

18.n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。 当一个数字删除后,从被删除数字的下一个继续删除第m个数字。 求出在这个圆圈中剩下的最后一个数字。

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4263868.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字). 当一个数字

Linux内核中的信号机制--一个简单的例子【转】

本文转载自:http://blog.csdn.net/ce123_zhouwei/article/details/8562958 Linux内核中的信号机制--一个简单的例子 Author:ce123(http://blog.csdn.NET/ce123) 信号机制是类UNIX系统中的一种重要的进程间通信手段之一.我们经常使用信号来向一个进程发送一个简短的消息.例如:假设我们启动一个进程通过socket读取远程主机发送过来的网络数据包,此时由于网络因素当前主机还没有收到相应的数据,当前进程被设置

Keil调试STM32中解析main开始前的工作

Cortex M3的内核有三种启动方式,其分别是: A.通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处: B.通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处: C.通过boot引脚设置可以将中断向量表定位于内置Bootloader区, Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,

java中生成流水号的一个例子(使用BerkeleyDB)

package com.jiaoyiping.berkeleydb; import com.sleepycat.je.*; import com.sleepycat.utilint.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; /** * Created with IntelliJ IDEA. * User: 焦一