一個簡單的IOCP伺服器例項
////////////////////////////////////////////////////////// // initsock.h檔案 #include <winsock2.h> #pragma comment(lib, "WS2_32") // 連結到WS2_32.lib class CInitSock { public: CInitSock(BYTE minorVer = 2, BYTE majorVer = 2) { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0) { exit(0); } } ~CInitSock() { ::WSACleanup(); } };
///////////////////////////////////////////////// // IOCPDemo.cpp檔案 除錯通過 #include "initsock.h" #include <stdio.h> #include <windows.h> // 初始化Winsock庫 CInitSock theSock; #define BUFFER_SIZE 1024 typedef struct _PER_HANDLE_DATA // per-handle資料 { SOCKET s; // 對應的套節字控制代碼 sockaddr_in addr; // 客戶方地址 } PER_HANDLE_DATA, *PPER_HANDLE_DATA; typedef struct _PER_IO_DATA // per-I/O資料 { OVERLAPPED ol; // 重疊結構 char buf[BUFFER_SIZE]; // 資料緩衝區 int nOperationType; // 操作型別 #define OP_READ 1 #define OP_WRITE 2 #define OP_ACCEPT 3 } PER_IO_DATA, *PPER_IO_DATA; DWORD WINAPI ServerThread(LPVOID lpParam) { // 得到完成埠物件控制代碼 HANDLE hCompletion = (HANDLE)lpParam; DWORD dwTrans; PPER_HANDLE_DATA pPerHandle; PPER_IO_DATA pPerIO; while(TRUE) { // 在關聯到此完成埠的所有套節字上等待I/O完成 BOOL bOK = ::GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPerHandle, (LPOVERLAPPED*)&pPerIO, WSA_INFINITE); if(!bOK) // 在此套節字上有錯誤發生 { ::closesocket(pPerHandle->s); ::GlobalFree(pPerHandle); ::GlobalFree(pPerIO); continue; } if(dwTrans == 0 && // 套節字被對方關閉 (pPerIO->nOperationType == OP_READ || pPerIO->nOperationType == OP_WRITE)) { ::closesocket(pPerHandle->s); ::GlobalFree(pPerHandle); ::GlobalFree(pPerIO); continue; } switch(pPerIO->nOperationType) // 通過per-I/O資料中的nOperationType域檢視什麼I/O請求完成了 { case OP_READ: // 完成一個接收請求 { static int count=1; pPerIO->buf[dwTrans] = '\0'; //printf(pPerIO -> buf); printf("第%d次接收到資料為:%s\n",count++,pPerIO->buf); // 繼續投遞接收I/O請求 WSABUF buf; buf.buf = pPerIO->buf ; buf.len = BUFFER_SIZE; pPerIO->nOperationType = OP_READ; DWORD nFlags = 0; ::WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, &pPerIO->ol, NULL); } break; case OP_WRITE: // 本例中沒有投遞這些型別的I/O請求 case OP_ACCEPT: break; } } return 0; } void main() { int nPort = 9090; // 建立完成埠物件,建立工作執行緒處理完成埠物件中事件 HANDLE hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); SYSTEM_INFO siSys; //獲取CPU數目 GetSystemInfo(&siSys); //建立一定數目的工作者執行緒,本例中以一個處理器一個執行緒搭配 for(int i = 0; i<(int)siSys.dwNumberOfProcessors*2; i++)//NumberOfProcessors { ::CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0); } // 建立監聽套節字,繫結到本地地址,開始監聽 SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN si; si.sin_family = AF_INET; si.sin_port = ::ntohs(nPort); si.sin_addr.S_un.S_addr = INADDR_ANY; ::bind(sListen, (sockaddr*)&si, sizeof(si)); ::listen(sListen, 5); // 迴圈處理到來的連線 while(TRUE) { // 等待接受未決的連線請求 SOCKADDR_IN saRemote; int nRemoteLen = sizeof(saRemote); SOCKET sNew = ::accept(sListen, (sockaddr*)&saRemote, &nRemoteLen); // 接受到新連線之後,為它建立一個per-handle資料,並將它們關聯到完成埠物件。 PPER_HANDLE_DATA pPerHandle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)); pPerHandle->s = sNew; memcpy(&pPerHandle->addr, &saRemote, nRemoteLen); ::CreateIoCompletionPort((HANDLE)pPerHandle->s, hCompletion, (DWORD)pPerHandle, 0); // 投遞一個接收請求 PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA)); pPerIO->nOperationType = OP_READ; WSABUF buf; buf.buf = pPerIO->buf; buf.len = BUFFER_SIZE; DWORD dwRecv; DWORD dwFlags = 0; ::WSARecv(pPerHandle->s, &buf, 1, &dwRecv, &dwFlags, &pPerIO->ol, NULL); } }
相關推薦
一個簡單的IOCP伺服器例項
////////////////////////////////////////////////////////// // initsock.h檔案 #include <winsock2.h> #pragma comment(lib, "WS2_32") //
一個簡單Python爬蟲例項(爬取的是前程無憂網的部分招聘資訊)
從今天開始學習爬蟲,展示我的第一個例項(用的是Python3寫的,Python2需要加個編碼方式吧,或許還有其他的不相容的地方吧,我就不知道了),把這分享給大家,希望對大家有一些幫助 import urllib,re import urllib.request import xlwt #開啟網頁
go搭建一個簡單web伺服器
Go語言裡面提供了一個完善的net/http包,通過http包可以很 方便的就搭建起來一個可以執行的web服務。同時使用這個包能很簡單地對web的路由,靜態檔案,模版,cookie等數 據進行設定和操
$python爬蟲系列(1)——一個簡單的爬蟲例項
本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。 1. 概述 本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。下載圖片的步驟如下: 獲取網頁html文字內容; 分析html中圖片的html標籤特徵,用正則解析出所有的
Windows 上靜態編譯 Libevent 2.0.10 並實現一個簡單 HTTP 伺服器
假設 Visual Studio 2005 的安裝路徑為“D:\Program Files\Microsoft Visual Studio 8\”,Libevent 2.0.10 解壓後的路徑為“D:\libevent-2.0.10-stable”。 編譯生成L
一個簡單web伺服器的java實現
一個簡單的web伺服器在不考慮其效能及健壯性的情況下,通常只需實現的功能包括伺服器的啟動,它用於監聽某一個埠,接收客戶端發來的請求,並將響應結果返回給客戶端。本文將介紹一個簡單web伺服器的實現原理,它本身只能處理某個目錄下的靜態資原始檔(文字、圖片等)。採用java
【Java.JMS】一個簡單的JMS例項
選擇ActiveMQ。 建立一個簡單的Maven工程,pom.xml如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-i
nodeJS從入門到放棄(一)用nodeJS搭建一個簡單的伺服器
現在前端招聘要求中,經常會傾向於招懂nodeJS的前端開發人員,說明懂nodeJS的前端是更具競爭力的,所以動起了學nodeJs的打算,作博n篇,鞏固總結+給後面的人鋪路 前端開發人員學習
C語言實現一個簡單的伺服器
C/S結構流程圖 服務端 socket函式 為了執行網路I/O,一個程序必須做的第一件事情就是建立一個socket函式 /* family 表示協議族 AF_INET(IPv4協議)、AF_INET6(IPv6協議)、AF_L
ROS的學習(十六)用C++寫一個簡單的伺服器(service)和客戶端(client)
我們將建立一個伺服器節點add_two_ints_server,它將會收到兩個整數,並且返回它們的和。切換目錄到之前建立的beginner_tutorials包下: cd ~/catkin_ws/src/beginner_tutorials 編輯sr
實現一個簡單的Spring例項
程式碼: 1.配置檔案 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="h
一個簡單的伺服器與客戶端程式
最近在學習《深入理解計算機系統》,看到linux系統級的IO以及,socket通訊,所以乾脆參考書上例程,自己著手寫一個客戶端與伺服器的小程式。 並未使用csapp封裝好的open_clientfd與open_listenfd還有RIO包 主要功能就兩個: 1.伺服器讀客戶
【Android 網路資料解析實現一個簡單的新聞例項(一)】
一般安卓在學到非同步任務AsyncTask之後都會有個安卓小專案的任務。得到(荔枝新聞,茶百科等)新聞網路介面來解析網路圖片或文字到ListView元件上顯示。其中要使用到的知識大概有:獲取網路資料(HttpUtil),解析網路資料(NewsParse),防止因
一個簡單的 SpringMVC 例項
新增 spring 框架所需的 jar 包。首先使用 Eclipse 新建一個動態的 Web 工程,命名為SpringMVCDome 如果沒有特別的要求可以將 spring-framework-4.2
微信企業號會議助手---一個簡單的SSM例項
前面基本的配置和工具類都差不多搞定了,如果有缺少在程式碼看到也不難理解了,下面來講一個小例子,迅速讓你理解ssm開發。 controller就是spring的控制器,所有前端的ajax的入口就在這,ajax怎麼進來呢? 我就講講一個跳轉到增加會議介面,和
一個簡單的REST例項
首先用ruby script/generate migration create_table_friends建立一個migration檔案, 寫入以下程式碼: class CreateTableFriends < ActiveRecord::Migration
j2EE一個簡單的servlet例項
1,手寫先一個jsp頁面核心程式碼如下: <body> <form name="hello" action="<%=request.getContextPath()%>/Test" method="post"> <p>歡迎進
Nodejs 一個簡單的後臺例項
學了兩天的nodejs,寫了一個簡單的後臺例項,還有配套的與後臺進行互動的簡單網頁。 頁面端使用了jQuery進行控制, 後臺使用nodejs作為操控語言,使用express執行網路操作 整個工程結構如下: 根目錄--------------
採用Java nio 實現的一個簡單的伺服器
伺服器程式碼: package server.nio; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream;
一個簡單的IOCP伺服器/客戶端類
Any new allocation using VirtualAlloc* will always be rounded up to 64 KB (page file size) boundary so that if you allocate a new VAS region bound to the p