日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > 網(wǎng)絡(luò)編程(56)—— Windows下使用IOCP構(gòu)建socket服務(wù)端

網(wǎng)絡(luò)編程(56)—— Windows下使用IOCP構(gòu)建socket服務(wù)端

來源:程序員人生   發(fā)布時間:2017-02-05 13:46:10 閱讀次數(shù):3478次

1、完成端口對象

        不同于IO堆疊對象在IO完成時通過觸發(fā)事件或觸發(fā)CompletionRoutine回調(diào)函數(shù),IOCP模型將socket和完成端口對象(CompletionPort,簡稱CP對象)綁定,當(dāng)IO操作完成時,會改變該對象的狀態(tài),而我們通過完成端口對象,即可以確認(rèn)IO操作是不是完成。

       創(chuàng)建完成端口對象的API以下:

HANDLE WINAPI CreateIoCompletionPort(
  __in     HANDLE FileHandle,
  __in_opt HANDLE ExistingCompletionPort,
  __in     ULONG_PTR CompletionKey,
  __in     DWORD NumberOfConcurrentThreads
);

CreateIoCompletionPort既可以創(chuàng)建完成端口對象,也能夠用來將socket和完成對象綁定,通過對其賦予不同的參數(shù),可以實(shí)現(xiàn)不同的功能:

FileHandle ——創(chuàng)建CP對象時傳入INVALID_HANDLE_VALUE;綁定socket和CP對象時傳入socket描寫符。

ExistingCompletionPort——創(chuàng)建CP對象時傳入NULL;綁定socket和CP對象傳入完成端口對象的句柄;

CompletionKey —— 創(chuàng)建CP對象是傳入0;綁定socket和CP對象時作為參數(shù)傳遞給GetQueuedCompletionStatus

NumberOfConcurrentThreads—— 分配給CP對象用于處理IO的線程數(shù)。如果參數(shù)是0,系統(tǒng)中的CPU個數(shù)就是最大的線程數(shù)。

返回值 —— 返回CP對象的句柄。

        以下,我們創(chuàng)建了1個完成端口對象:

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

2、進(jìn)行socket對象和CP對象的綁定

        我們依然用CreateIoCompletionPort將socket和CP對象進(jìn)行綁定:

CreateIoCompletionPort((HANDLE)clntSock,hComPort,(DWORD)handleInfo,0);

        clntSock是我們要進(jìn)行綁定的socket描寫符,hComPort使我們之前創(chuàng)建的CP對象,而handleInfo是我們自定義的結(jié)構(gòu)體,作為參數(shù)可以傳給GetQueuedCompletionStatus函數(shù)。

3、使用GetQueuedCompletionStatus獲得CP對象的狀態(tài)

        GetQueuedCompletionStatus在我們定義的線程函數(shù)中調(diào)用,用于獲得CP對象的狀態(tài)。當(dāng)IO操作未完成時,該函數(shù)會產(chǎn)生阻塞;若IO操作完成,函數(shù)產(chǎn)生返回。其函數(shù)原型以下:

BOOL WINAPI GetQueuedCompletionStatus(
  __in  HANDLE CompletionPort,
  __out LPDWORD lpNumberOfBytes,
  __out PULONG_PTR lpCompletionKey,
  __out LPOVERLAPPED *lpOverlapped,
  __in  DWORD dwMilliseconds
);

CompletionPort —— 進(jìn)行注冊過的完成對象的句柄。

lpNumberOfBytes —— 完成IO對象時傳遞或接受的字節(jié)數(shù)。

lpCompletionKey —— 使用CreateIoCompletionPort注冊時傳遞的參數(shù),參數(shù)可以傳遞我們自定義的結(jié)構(gòu)信息。

lpOverlapped —— 調(diào)用WSARecv或WSASend時傳遞的OVERLAPPED對象指針。

dwMilliseconds —— GetQueuedCompletionStatus阻塞的時間,如果設(shè)置成INFINITE時無窮期等待。

4、代碼示例

#include "stdafx.h"
#include "stdio.h"
#include "process.h"
#include "stdlib.h"
#include "WinSock2.h"
#include "Windows.h"
 
#pragma comment(lib,"ws2_32.lib")
 
#define BUF_SIZE 100
#define READ 3
#define WRITE 5
 
typedef struct 
{
    SOCKEThClntSock;
    SOCKADDRclntAdr;
}HANDLE_DATA,*LPHANDLE_DATA;
 
typedef struct
{
    OVERLAPPEDoverlapped;
    WSABUFwsaBuf;
    char buffer[BUF_SIZE];
    int rwMode;
}IO_DATA,*LPIO_DATA;
 
unsigned WINAPI ThreadMain(LPVOID CompletionPortIO);
void ErrorHandler(char* message);
 
int _tmain(int argc, _TCHAR* argv[])
{
    WSADatawsaData;
    HANDLEhComPort;
    SYSTEM_INFOsysInfo;
    LPIO_DATAioInfo;
    LPHANDLE_DATAhandleInfo;
 
    SOCKETservSock;
    SOCKADDR_INservAddr;
    DWORDrecvBytes,i,flags=0;
    WSAStartup(MAKEWORD(2,2),&wsaData);
   
    hComPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
    GetSystemInfo(&sysInfo);
 
    for(i=0;i<sysInfo.dwNumberOfProcessors;i++)
        _beginthreadex(NULL,0,ThreadMain,(LPVOID)hComPort,0,NULL);
 
    servSock=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
    if(servSock==INVALID_SOCKET)
        ErrorHandler("WSASocket Error");
 
    memset(&servAddr,0,sizeof(servAddr));
    servAddr.sin_family=AF_INET;
    servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servAddr.sin_port=htons(atoi("8888"));
 
    if(bind(servSock,(SOCKADDR*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
        ErrorHandler("bind error");
 
    if(listen(servSock,5)==SOCKET_ERROR)
        ErrorHandler("listen error");
 
    while(1)
    {
        SOCKETclntSock;
        SOCKADDR_INclntAddr;
        int clntAddrSz;
 
        clntSock=accept(servSock,(SOCKADDR*)&clntAddr,&clntAddrSz);
        handleInfo=(LPHANDLE_DATA)malloc(sizeof(HANDLE_DATA));
        handleInfo->hClntSock=clntSock;
        memcpy(&(handleInfo->clntAdr),&clntAddr,sizeof(clntAddr));
 
        CreateIoCompletionPort((HANDLE)clntSock,hComPort,(DWORD)handleInfo,0);
 
        ioInfo=(LPIO_DATA)malloc(sizeof(IO_DATA));
        memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
        ioInfo->wsaBuf.len=BUF_SIZE;
        ioInfo->wsaBuf.buf=ioInfo->buffer;
        ioInfo->rwMode=READ;
        WSARecv(handleInfo->hClntSock,&(ioInfo->wsaBuf),1,&recvBytes,&flags,&(ioInfo->overlapped),NULL);
    }
   
    WSACleanup();
    return 0;
}
 
unsigned WINAPI ThreadMain(LPVOID CompletionPortIO)
{
    HANDLEhComPort=(HANDLE)CompletionPortIO;
    SOCKET sock;
    DWORDbytesTrans;
    LPHANDLE_DATAhandleInfo;
    LPIO_DATAioInfo;
    DWORD flags;
 
    while(1)
    {
    GetQueuedCompletionStatus(hComPort,&bytesTrans,(PULONG_PTR)&handleInfo,(LPOVERLAPPED*)&ioInfo,INFINITE);
        sock=handleInfo->hClntSock;
 
        if(ioInfo->rwMode==READ)
        {
            puts("message received!");
            if(bytesTrans==0)
            {
                closesocket(sock);
                free(handleInfo);
                free(ioInfo);
                continue;
            }
            memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
            ioInfo->wsaBuf.len=bytesTrans;
            ioInfo->rwMode=WRITE;
            WSASend(sock,&(ioInfo->wsaBuf),1,NULL,0,&(ioInfo->overlapped),NULL);
 
            ioInfo=(LPIO_DATA)malloc(sizeof(IO_DATA));
            memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
            ioInfo->wsaBuf.len=BUF_SIZE;
            ioInfo->wsaBuf.buf=ioInfo->buffer;
            ioInfo->rwMode=READ;
            WSARecv(sock,&(ioInfo->wsaBuf),1,NULL,&flags,&(ioInfo->overlapped),NULL);
        }
        else
        {
            puts("message sent");
            free(ioInfo);
        }
    }
    return 0;
}
 
void ErrorHandler(char* message)
{
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}


 Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本項(xiàng)目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
獲得本文源代碼:
git checkout NL56


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲国产精品麻豆 | 国产亚洲精品久久久久动 | 国产91亚洲 | 亚洲国产成人精品女人久久久 | 国产最新视频 | 久久国产精品伦理 | 国产91av在线 | av老司机在线观看 | 国产精品久久久久久久久久久不卡 | 免费在线观看 av | 日韩精品视频一区二区三区 | 国内毛片毛片 | 欧美成人三区 | 91麻豆视频 | 国产精品网址 | 亚洲国产高清视频 | 欧美日韩在线视频一区二区 | 国产精品一国产精品 | www欧美| 国产精品美乳一区二区免费 | 日韩欧美在线不卡 | 国产精品美女久久久久久久网站 | 久久国产精品-国产精品 | 伊人中文 | 国产传媒一区二区三区 | 亚洲精品一区二区网址 | 亚洲国产美女 | 精品九九久久 | 色婷婷狠狠 | 久艹久久| 91精品国产综合久久久久久丝袜 | 能看av的网址 | 国产精品无码永久免费888 | 亚洲国产精品国自产拍av秋霞 | 日韩午夜视频在线观看 | 五月婷婷激情综合网 | 成人激情视频在线 | 精品一区二区三区免费毛片爱 | 黄色大片电影 | 精品国产鲁一鲁一区二区张丽 | 欧美午夜一区二区 |