zoukankan      html  css  js  c++  java
  • 学习笔记之WSAAsyncSelect模式

    大体原理:WSAAsyncSelect模式允许以windows消息的形式接收网络事件通知。这个模式是为了适应windows消息驱动环境而设置的,对性能要求不高的网络应用程序可采用此模式。

    要注意的地方:网络事件消息抵达消息处理函数后,应用程序首先检查Lparam参数的高位,以判断在套接字上发生了网络错误。宏WSAGETSELECTERROR返回高字节包含的错误信息。若应用程序发现套接字上没有产生任何错误便可用宏WSAGETSELECTEVENT读取LPARAM参数的低字位确定发生的网络事件。

    优缺点:WSAAsyncSelect模型最突出的特点是与windows的消息驱动机制融在了一起,这使得开发带GUI界面的网络程序变得很简单。但是如果连接增加,单个WINDOWS函数处理上千个客户请求时,服务器性能势必发受到影响。

    主要函数:WSAAsyncSelect。

    主要参数:发送的通知码含义:

    FD_READ:套接字接收到对方发送过来的数据包,表明可以去读套接字了。

    FD_WRITE: 数据缓冲区满后再次变空时,通知应用 程序可以继续发送数据了。

               注:send函数先将要发送的数据放入缓冲区中后,由windows负责将数据发送出去。如果缓冲区满了, 则不能发送数据了。当FD_WRITE后,可以再发送数据。

    FD_ACCEPT,FD_CONNECT,FD_CLOSE。看单词就明白了。

    DELPHI代码:

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,JwaWinsock2;
    const
      WM_SOCKET=WM_USER+100;
    type
      TForm1 = class(TForm)
        mmo1: TMemo;
        btn1: TButton;
        mmo2: TMemo;
        btn2: TButton;
        procedure FormCreate(Sender: TObject);
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        procedure Self_WndProc(var Msg: TMessage);  //拦截窗体的所有消息
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;
      Oldwindowproc:TWndMethod;
      sListen:TSocket;
      WSData: TWSAData;
    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      OldWindowProc   := Self.WindowProc; //保存原来的函数地址;
      Self.WindowProc :=Self_WndProc;     //指定新的函数地址;
      WSAStartup($0202, WSData);
      sListen:=INVALID_SOCKET;
      sListen:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    end;
    procedure TForm1.Self_WndProc(var msg:TMessage);
    var
      sClient, sEvent: TSocket;
      addrRemote: TSockAddrIn;
      addrlen:Integer;
      szText:array[0..255] of AnsiChar;
    begin
      if Msg.Msg=WM_SOCKET then
        begin
          sEvent:=Msg.WParam;
          if WSAGETASYNCERROR(Msg.LParam)<>0 then
            begin
              closesocket(sEvent);
            end
          else
            begin
              case WSAGETSELECTEVENT(Msg.LParam) of
                FD_ACCEPT:  //当监听到套接字有连接进入时。
                  begin
                    addrlen:=SizeOf(addrRemote);
                    sClient:=accept(sEvent,psockaddr(@addrRemote),@addrlen);
                    WSAAsyncSelect(sClient,Self.Handle,WM_SOCKET,FD_ACCEPT or FD_CLOSE or FD_READ or FD_WRITE);
                    mmo1.Lines.Add('当前连接IP信息:'+strpas(inet_ntoa(addrRemote.sin_addr)));
                  end;
                FD_WRITE:
                  begin

                  end;
                FD_READ:
                  begin
                    if recv(sEvent,szText,SizeOf(szText),0)>0 then
                         begin
                           mmo2.Lines.Add('接收的数据是:'+strpas(sztext));
                         end
                       else
                         begin
                           closesocket(sEvent);
                         end;
                  end;
                FD_CLOSE:
                   begin
                     closesocket(sEvent);
                     mmo1.Lines.Add('用户断开连接。');
                   end;
              end;
            end;
        end;
       OldWindowProc(Msg);
    end;
    procedure TForm1.btn1Click(Sender: TObject);    //启动临听服务
    var
      sins:sockaddr_in;
    begin
     if sListen<>INVALID_SOCKET then
       begin
         Sins.sin_family  :=AF_INET;
         sins.sin_port    :=htons(4567);
         sins.sin_addr.S_addr:=INADDR_ANY;
         if bind(sListen,@sins,SizeOf(sins))=SOCKET_ERROR then
          begin
             ShowMessage('无法进行端口绑定。');
             Exit;
          end;
         WSAAsyncSelect(sListen,Self.Handle,WM_SOCKET,FD_ACCEPT or FD_CLOSE or FD_READ or FD_WRITE);
         listen(sListen,5);
         btn1.Enabled:=False;
       end;

  • 相关阅读:
    HDU2027 统计元音 一点点哈希思想
    湖南工业大学第一届ACM竞赛 数字游戏 字符串处理
    湖南工业大学第一届ACM竞赛 我素故我在 DFS
    HDU3293sort
    HDU2082 找单词 母函数
    HDU1018 Big Number 斯特林公式
    湖南工业大学第一届ACM竞赛 分糖果 位操作
    UVA 357 Let Me Count The Ways
    UVA 147 Dollars
    UVA 348 Optimal Array Multiplication Sequence
  • 原文地址:https://www.cnblogs.com/wangorg/p/2032996.html
Copyright © 2011-2022 走看看