1. 程式人生 > >伺服器端WSAAsyncSelect模型程式設計

伺服器端WSAAsyncSelect模型程式設計

WSAAsyncSelect是伺服器端的六種I/O模型之一,他的主要思想是運用了windows視窗的訊息機制,用函式WSAAsyncSelect()將監聽埠感興趣的網路訊息註冊到視窗,然後在視窗的訊息過程中處理,該模型只提供非同步通知,並不提供非同步資料傳送,只適用於系統開銷不大的情況。

使用該模型程式設計,需要基於視窗,以下CreateServerWindow提供了建立視窗的過程。

#include <cassert>
#include <iostream>
#include "ServerWindowCreator.h"
#include "SocketUtil.h"

HWND ServerWindowCreator::CreateServerWindow(HINSTANCE hInstance, LPCTSTR wndClass, WNDPROC wndProc)
{
	assert(hInstance);
	assert(wndClass);
	assert(wndProc);
	if(!hInstance || !wndClass || !wndProc)
		return NULL;

	HWND hWnd = NULL;
	if (MyRegisterClass(hInstance, wndClass, wndProc))//註冊視窗類
		hWnd = InitInstance(hInstance, wndClass);//建立視窗

	return hWnd;
}

bool ServerWindowCreator::MyRegisterClass(HINSTANCE hInstance, LPCTSTR wndClass, WNDPROC wndProc)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= 0;
	wcex.lpfnWndProc	= wndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= NULL;
	wcex.hbrBackground	= NULL;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= wndClass;
	wcex.hIconSm		= NULL;

	ATOM ret = RegisterClassEx(&wcex);
	assert(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
	return ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS;
}

HWND ServerWindowCreator::InitInstance(HINSTANCE hInstance, LPCTSTR wndClass)
{
	HWND hWnd = CreateWindow(wndClass, NULL, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, 0, 0, NULL, NULL, hInstance, NULL);
	
	assert(hWnd);
	if(!hWnd)
	{
		DWORD dwError = GetLastError();
		std::cout<<"create server window failed"<<std::endl;
	}

	return hWnd;
}


伺服器端的通訊過程

#include "SocketUtil.h"
#include "ServerWindowCreator.h"
#include "ServerSourceHolder.h"
#include "ServerParamDef.h"
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance, LPSTR lpCmdLine,
	int nCmdShow)
{
	ServerHolder skHoder;//該物件負責管理winsock庫的初始化和清理,監聽socket的釋放,視窗的資源和訊息管理
	if (!skHoder.Init())
		return 0;

	SOCKET skListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//建立監聽socket
	if (skListen == INVALID_SOCKET)
	{
		RecordSocketError("create listen socket failed");
		return 0;
	}
	std::cout<<"listen socket = "<<skListen<<std::endl;
	skHoder.HoldSocketFd(skListen);

	sockaddr_in addr;
	memset(&addr, NULL, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(SERVER_PORT);
	if (bind(skListen, (sockaddr*)&addr, sizeof(addr)))//將socket與地址繫結
	{
		RecordSocketError("bind address failed");
		return 0;
	}

	const TCHAR* WINDOW_CLASS = _T("ServerWindow");//建立視窗
	HWND hWnd = ServerWindowCreator::CreateServerWindow(hInstance, WINDOW_CLASS, 
		ServerHolder::ServerWndProc);
	if (!hWnd || !::IsWindow(hWnd))
		return 0;

	skHoder.HoldWindow(hWnd);

	if (WSAAsyncSelect(skListen, hWnd, WM_SOCKET,
		FD_ACCEPT | FD_CLOSE | FD_WRITE) != 0)//註冊網路訊息
	{
		RecordSocketError("set socket error");
		return 0;
	}

	if (listen(skListen, MAX_PENDING_CONN) != 0) //開始監聽
	{
		RecordSocketError("listen error");
		return 0;
	}

	std::cout<<"start server ..."<<std::endl;
	ServerHolder::ServerMessageLoop();//進入視窗訊息迴圈

	return 0;
}


WSAAsyncSelect模型的基礎程式設計可以參考《windows網路程式設計第二版》,裡面有比較詳細的介紹。

相關推薦

伺服器WSAAsyncSelect模型程式設計

WSAAsyncSelect是伺服器端的六種I/O模型之一,他的主要思想是運用了windows視窗的訊息機制,用函式WSAAsyncSelect()將監聽埠感興趣的網路訊息註冊到視窗,然後在視窗的訊息過程中處理,該模型只提供非同步通知,並不提供非同步資料傳送,只適用於系統開

幾種伺服器IO模型的簡單介紹及實現

一些概念: 同步和非同步 同步和非同步是針對應用程式和核心的互動而言的,同步指的是使用者程序觸發I/O操作並等待或者輪詢的去檢視I/O操作是否就緒,而非同步是指使用者程序觸發I/O操作以後便開始做自己的事情,而當I/O操作已經完成的時候會得到I/O完成的通知。 阻塞和非阻塞 阻塞和非阻塞是針對於程序在

高效能伺服器網路程式設計模型

  上一篇文章《Java 程式設計師也需要了解的 IO 模型》中講到伺服器端高效能網路程式設計的核心在於架構,而架構的核心在於程序-執行緒模型的選擇。本文將主要介紹傳統的和目前流行的程序-執行緒模型,在講程序-執行緒程模型之前需要先介紹一種設計模式: Reactor&n

Python下UDP的Socket程式設計伺服器因客戶的非正常退出而報錯?

伺服器端程式碼 import socket import threading import logging import datetime logging.basicConfig(format='%(message)s', level=logging.INFO) class ChatUd

計算機網路_伺服器只能處理一個客戶_模型

一、 需要知道 1.1 套接字 套接字是通訊端點的抽象。套接字描述符類似於檔案描述符。 accept recv阻塞執行。 int listen(int sockfd, int size);  早期版本size含義是伺服器能維護的已完成的連線和正在連線的佇列的大小,有兩個

《網路遊戲伺服器程式設計》——學習筆記(day1)

宣告 本人萌新一枚,以後想進入遊戲開發行業,so,開始自學《網路遊戲伺服器端程式設計》一書,在部落格上寫筆記以記錄提取一些書中我自認為有用的知識點,如有侵權或者一些別的問題,請私信我,謝謝! 網路程式設計基礎 網路遊戲伺服器端開發概述 Client/Serve

C#程式設計 socket程式設計之tcp伺服器和客戶

基於Tcp協議的Socket通訊類似於B/S架構,面向連線,但不同的是伺服器端可以向客戶端主動推送訊息。 使用Tcp協議通訊需要具備以下幾個條件: (1).建立一個套接字(Socket) (2).繫結伺服器端IP地址及埠號--伺服器端 (3).利用Listen()方法開啟監聽--伺服

C#程式設計 socket程式設計之udp伺服器和客戶

基於Udp協議是無連線模式通訊,佔用資源少,響應速度快,延時低。至於可靠性,可通過應用層的控制來滿足。(不可靠連線) 使用Udp協議通訊需要具備以下幾個條件: (1).建立一個套接字(Socket) (2).繫結伺服器端IP地址及埠號--伺服器端 (3).通過SendTo()方法向指

網路程式設計實驗四——利用多程序和多執行緒實現伺服器的併發處理

一、實驗目的 1.在TCP檔案傳輸程式碼的基礎上,利用多程序實現伺服器端的併發處理。  2.利用多執行緒實現伺服器端的併發處理。 二、實驗原理 併發的面向連線伺服器演算法: 主1、建立套接字並將其繫結到所提供服務的熟知地址上。讓該套接字保持為無連線的。 主2、將

網路程式設計——6. 基於UDP的伺服器/客戶

6.1 理解UDP UDP套接字的特點 跟寄信一樣,我寫好名字和地址,貼上郵票寄出去就好了。 郵寄過程的丟失或者損壞我都沒辦法保證,是一種不可靠的傳輸方式。但相比TCP,雖然可靠性差一些,但比TCP簡潔一些,速度也更快一些(在每次交換的資料量越小的情況下)。。

網路程式設計——4.利用多程序和多執行緒實現伺服器的併發處理

一、實驗要求     在TCP檔案傳輸程式碼的基礎上,利用單執行緒程序併發模型和多執行緒併發模型實現伺服器端的併發處理。 二、實驗分析     多執行緒與多程序相比,使用多執行緒相比多程序有以下兩個優點:更高的效率和共享儲存器,效率的提高源於上下文切換次數的減少。

python網路程式設計(TCP客戶/伺服器實現)

下面的程式實現的功能:客戶端發來訊息,伺服器端加上時間戳返回給使用者 伺服器端: from socket import * from time import ctime import os p

TCP/IP網路程式設計 基於Linux程式設計_4 --多執行緒伺服器的實現

執行緒基本概念 前面我們講過多程序伺服器,但我們知道它開銷很大,因此我們才引入執行緒,我們可以把它看成是一種輕量級程序。它相比程序有如下幾個優點: 執行緒的建立和上下文切換開銷更小且速度更快。 執行緒間交換資料時無需特殊技術。 程序:在作業系統構成

伺服器程式設計心得(七)——開源一款即時通訊軟體的原始碼

        在我的《伺服器端程式設計心得》這個系列的第一篇至第六篇都是講了一些零散的不成體系的網路程式設計細節。今天,在這篇文章中,我將介紹一款我自主開發的即時通訊軟體flamingo(中文:火烈鳥),並開源其伺服器和pc客戶端程式碼。以此來對前幾篇文章中說到的理論進行實

TCP伺服器和客戶程式設計

1、socket函式:為了執行網路輸入輸出,一個程序必須做的第一件事就是呼叫socket函式獲得一個檔案描述符。 -----------------------------------------------------------------  #include <sys/socket.h>

伺服器程式設計心得(三)—— 一個伺服器程式的架構介紹

本文將介紹我曾經做過的一個專案的伺服器架構和伺服器程式設計的一些重要細節。 一、程式執行環境 作業系統:centos 7.0 編譯器:gcc/g++ 4.8.3     cmake 2.8.11 my

java-基本的Socket程式設計-實現伺服器和客戶通訊

基本的Socket程式設計: 本例項介紹Socket程式設計的基本步驟。啟動Socket服務後,再開啟Socket刻畫段,在輸入框中輸入訊息,然後傳送給伺服器端,伺服器端將收到的訊息返回到客戶端。 關鍵技術: Socket程式設計的關鍵技術如下; —–S

socket 程式設計 伺服器-客戶

socket 程式設計 伺服器端-客戶端 /**** 伺服器端程式碼 *****/ #include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<

tcp/ip 多執行緒伺服器的實現(參考tcp/ip網路程式設計

執行緒的切換比程序快的多,因為它不需要切換資料區和堆 共享資料區和堆可以用來交換資訊 一、執行緒的建立 pthread_create()函式 #include<pthread.h> int prthread_create(pthread * thread,c

網路程式設計伺服器繫結ip設定

在使用socket編寫伺服器程式時,設定伺服器繫結的sockaddr_in結構往往會困擾很多同學,sockaddr_in結構中sin_famliy和sin_port(注意要使用htons轉換為網路序