基于异步选择模型的服务器实践

4人阅读 评论(0) 收藏 举报
分类:
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
using namespace std;
#define MAXDATASIZE 200

typedef struct _SOCKET_INFORMATION
{
    char buf[MAXDATASIZE];
    WSABUF DataBuf;
    SOCKET Socket;
    _SOCKET_INFORMATION *Next;

}SOCKET_INFORMATION, *LPSOCKET_INFORMATION;

#define BACKLOG 5
#define WM_SOCKET (WM_USER + 1)
LPSOCKET_INFORMATION SocketInfoList = NULL;
char buf[MAXDATASIZE];
SOCKET Accept;

void CreateSocketInformation(SOCKET s)
{
    LPSOCKET_INFORMATION SI;
    SI = (LPSOCKET_INFORMATION)GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION));
    if (SI == NULL)
    {
        printf("GlobalAlloc() failed with error %d.\n", GetLastError());
        return;
    }
    SI->Socket = s;
    SI->Next = SocketInfoList;
    SocketInfoList = SI;
}

LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)
{
    LPSOCKET_INFORMATION SI = SocketInfoList;
    while (SI)
    {
        if (SI->Socket == s)
            return SI;
        SI = SI->Next;
    }
    return NULL;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LPSOCKET_INFORMATION SocketInfo;
    int sb, BytesRecv = 0;
    if (uMsg == WM_SOCKET)
    {
        if (WSAGETSELECTERROR(lParam))
        {
            printf("Socket failed with error %d.\n", WSAGETSELECTERROR(lParam));
        }
        else
        {
            switch (WSAGETSELECTEVENT(lParam))
            {
            case FD_ACCEPT:
                Accept = accept(wParam, NULL, NULL);
                if (Accept == INVALID_SOCKET)
                {
                    printf("accept() failed with error %d.\n", WSAGetLastError());
                    break;
                }
                WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE);
                CreateSocketInformation(Accept);
                break;
            case FD_READ:
                SocketInfo = GetSocketInformation(wParam);
                BytesRecv = recv(SocketInfo->Socket, buf, MAXDATASIZE, 0);
                if (BytesRecv > 0)
                {
                    buf[BytesRecv] = '\0';
                    printf("recv : %s\n", buf);
                }
                break;
            case FD_CLOSE:
                SocketInfo = GetSocketInformation(wParam);
                printf("Socket %d closed.\n", SocketInfo->Socket);
                closesocket(SocketInfo->Socket);
                break;
            }
        }
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

HWND MakeWorkerWindow(void)
{
    WNDCLASSEX wndclass;
    WCHAR ProviderClass[] = L"AsyncSelect";
    WCHAR WindowName[] = L"";
    HWND Window;

    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = (WNDPROC)WindowProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = NULL;
    wndclass.hIcon = LoadIcon(NULL, IDI_WARNING);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = ProviderClass;
    wndclass.hIconSm = NULL;
    if (RegisterClassEx(&wndclass) == 0)
    {
        printf("RegisterClassEx() failed with error %d.\n", GetLastError());
        return NULL;
    }
    Window = CreateWindow(ProviderClass, WindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, NULL, NULL, NULL, NULL);
    if (Window == NULL)
    {
        printf("CreateWindow() failed with error %d.\n", GetLastError());
        return NULL;
    }
    return Window;
}

int main()
{
    MSG msg;
    DWORD ret;
    
    HWND Window = MakeWorkerWindow();
    if (Window == NULL)
    {
        return 0;
    }
    WSADATA wsadata;
    WSAStartup(0x0202, &wsadata);

    SOCKET sockfd;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    WSAAsyncSelect(sockfd, Window, WM_SOCKET, FD_ACCEPT);

    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(27105);
    myaddr.sin_addr.s_addr = INADDR_ANY;
    bind(sockfd, (SOCKADDR*)&myaddr, sizeof(myaddr));
    listen(sockfd, BACKLOG);

    printf("Server starts listening...\n");
    while (ret = GetMessage(&msg, NULL, 0, 0))
    {
        if (ret == -1)
        {
            printf("GetMessage failed with error %d.\n", GetLastError());
            return 0;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    closesocket(sockfd);
    WSACleanup();
    system("pause");
    return 0;
}
查看评论

(二)Socket I/O模型之异步选择(WSAAsyncSelect)

转自:点击打开链接 使用异步选择模型,应用程序可在一个套接字上,接收以Windows消息为基础的网络事件通知。具体的做法是在建好一个套接字后,调用WSAAsyncSelect函数。  ...
  • CTO_51
  • CTO_51
  • 2013-04-23 18:17:45
  • 904

WSAAsyncSelect基于Windows消息机制异步I/O模型(TCP)

  • 2010年09月19日 21:02
  • 87KB
  • 下载

异步选择模型WSAAsyncSelect

异步选择(WSAAsyncSelect)模型是一个有用的异步 I/O 模型。利用这个模型,应用程序可在一个套接字上,接收以 Windows 消息为基础的网络事件通知。具体 的做法是在建好一个套接字后,...
  • rankun1
  • rankun1
  • 2015-11-05 22:02:42
  • 587

二、异步选择模型(WSAAsyncSelect)

█ 异步选择(WSAAsyncSelect)模型是一个有用的异步 I/O 模型。利用这个模型,应用程序可在一个套接字上, 接收以 Windows 消息为基础的网络事件通知。具体的做法是在建好一个套接...
  • l_stream
  • l_stream
  • 2012-04-20 10:44:56
  • 1888

基于事件的选择模型服务器实践

#include &quot;winsock2.h&quot;#pragma comment(lib, &quot;ws2_32.lib&quot;)#include &amp;lt;iostream...
  • Datura_Metel
  • Datura_Metel
  • 2018-04-17 22:29:49
  • 3

异步编程和事件模型

网络编程其实很大一部分的内容就是处理各种IO,对IO模型的理解,能使我们对UB模型机制更深一层的理解。特别是下面会说到的异步编程和事件模型。 1. 同步阻塞IO 同步阻塞IO模型如下图。 ...
  • robert198837
  • robert198837
  • 2016-08-22 19:49:44
  • 736

Socket编程模型之事件选择模型

Winsock提供了另一个有用的异步I/O模型。和WSAAsyncSelect模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知。对于表1总结的、由WSAAsyncSe...
  • caoshiying
  • caoshiying
  • 2016-09-24 10:35:04
  • 1575

VC异步选择实例

  • 2011年11月01日 20:34
  • 2.81MB
  • 下载

异步/多线程/任务/并行编程之一:如何选择合适的多线程模型?(转)

异步、多线程、任务、并行编程之一:选择合适的多线程模型 本篇概述: @FCL4.0中已经存在的线程模型,以及它们之间异同点; @多线程编程模型的选择。   1:异步、多线程、任务、并行的...
  • fjl2014
  • fjl2014
  • 2016-04-21 21:44:07
  • 512

WSAAsyncselect 模型中,服务器与客户端消息的收发

WSAAsyncselect 模型中,服务器与客户端消息的收发 新建一�?/span>MFC对话框程�?/font> 服务器与客户端的对话框基本一致,以服务器为例�?/span>   ...
  • yulinxx
  • yulinxx
  • 2014-05-30 17:43:17
  • 1902
    个人资料
    等级:
    访问量: 453
    积分: 178
    排名: 102万+
    文章存档
    最新评论