• 2006-10-25

    重叠I/O - [多线程程序设计]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://xingzhesun.blogbus.com/logs/3680259.html

    重叠模型就是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或者多个winsock i/0请求。针对这些请求,在他们完成之后,应用程序会收到通知,于是就可以用自己的代码来处理这些数据了。
    有两个方法来管理重叠i/o请求的完成情况(就是说接到重叠操作完成的通知): 时间通知 和 完成例程。
    基于事件通知:就是把windows事件和WSAOVERLAPPED结构关联在一起。使用WSASend, WSASendto,WSARecvFrom。可以把重叠结构与这些函数绑定在一起,提交请求,其他的事情就交给重叠结构去操心了。这样我们就可以坐享其成了,等到重叠结构完成之后,自然会有与之对应的事件来通知我们。我们根据重叠操作的结果取得我们需要的数据。
    1。WSAOVERLAPPED
    WSAEVENT event;
    WSAOVERLAPPED AcceptOverlapped;
    event = WSACreateEvent();
    ZeroMemory(&Acceptoverlapped, sizeof(WSAOVERLAPPED));
    AccepOverlapped.hEvent = event;
    2. WSARecv系列函数

    SOCKET S;
    WSABUF DataBuf;
    char buffer[5095];
    ZeroMemorry(buffer,5095);
    DataBuf.len = 5095;

    DWORD dwBufferCount = 1, dwRecvBytes = 0, Flags = 0;
    WSAOVERLAPPED AcceptOVerlapped;
    WSAEVENT event;
    event = WSACreateEvent();
    ZeroMemory(&Acceptoverlapped, sizeof(WSAOVERLAPPED));
    AcceptOverlapped.hEvent = event;

    WSARecv(s, &DataBuf, dwBufferCount,&dwRecvBytes, &Flags, &AcceptOverlapped,NULL);

    3.WSAWaitForMultipleEvents
    等待事件的触发。

    4.WSAGetOverlappedResult
    查询重叠操作的结果。


    [1] 定义变量
    #define DATA_BUFSIZE 4096

    SOCKET ListenSocket;//监听套节字
    Socket AcceptSocket;//与客户端通信的套节字
    WSAOVERLAPPED AcceptOverlapped;//重叠结构
    WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];//用来通知重叠操作完成的事件句柄数组
    WSABUF DataBuf[WSA_MAXIMUM_WAIT_EVENTS];
    DWORD dwEventTotal = 0;//事件总数
    DWORD dwRecvBytes = 0;//接收的字符长度
    Flags= 0 ;
    [2] 创建套节字并在指定的端口上监听连接请求。
    WSADATA wsaData;
    WSAStartup();

    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    SOCKADDR_IN ServerAddr;
    serverAddr.sin.family = AF_INET;
    serverAddr.sin.addr.S_un.S_addr = htonl(INNADDR_ANY);
    serverAddr.sin_port = htons(11111);

    bind(ListenSocket, &serveraddr, sizeof());

    listen(Listensocket,5);
    [3] 接收一个入站的连接请求。
    SOCKADDR_IN clientAddr;
    int addr_length = sizeof(clientAddr);
    AcceptSocket= accept(ListenSocket, &clientsocket, &addr_length);
    LPCTSTR lpIP = inet_ntoa(clientAddr.sin_addr);//client ip
    UINT nPort = clientAddr.sin_port;//client port

    [4]建立并初始化重叠结构

    EventArray[dwEventTotal] = WSACreateEvent;
    ZeroMemory(&Acceptoverlapped, sizeof(WSAOVERLAPPED));
    AcceptOverlapped.hEvent = EventArray[dwEventTotal];//关联事件

    char buffer[DATA_BUFSIZE];
    ZeroMemory(buffer, DATA_BUFSIZE);

    DataBuffer.len = DATA_BUFFER;//初始化一个WSABUF结构
    DataBuffer.buf = buffer;

    dwEventTotal++;
    [5] 以WSAOVERLAPPED为参数,在套节字上投递WSARecv请求。

     


    收藏到:Del.icio.us