DIOCP之DEMO-登陆验证设计(二)
ECHOServer代码(不考虑粘包的处理):
unit ufrmMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ActnList, diocp_tcp_server, ExtCtrls,
  ComCtrls, utils_safeLogger, utils_BufferPool, utils_fileWriter, System.Actions, ComObj;
type
  TfrmMain = class(TForm)
    edtPort: TEdit;
    btnOpen: TButton;
    actlstMain: TActionList;
    actOpen: TAction;
    actStop: TAction;
    btnDisconectAll: TButton;
    pgcMain: TPageControl;
    TabSheet1: TTabSheet;
    tsLog: TTabSheet;
    mmoLog: TMemo;
    pnlMonitor: TPanel;
    btnGetWorkerState: TButton;
    btnFindContext: TButton;
    pnlTop: TPanel;
    btnPostWSAClose: TButton;
    btnReOpenTest: TButton;
    tmrKickOut: TTimer;
    tmrTest: TTimer;
    tmrInfo: TTimer;
    chkLogDetails: TCheckBox;
    tsOperator: TTabSheet;
    mmoPushData: TMemo;
    btnPushToAll: TButton;
    actPushToAll: TAction;
    btnPoolInfo: TButton;
    edtThread: TEdit;
    chkEcho: TCheckBox;
    chkShowInMemo: TCheckBox;
    chkSaveToFile: TCheckBox;
    chkUseContextPool: TCheckBox;
    chkUseBufferPool: TCheckBox;
    mmo1: TMemo;
    btn1: TButton;
    mmo2: TMemo;
    procedure actOpenExecute(Sender: TObject);
    procedure actPushToAllExecute(Sender: TObject);
    procedure actStopExecute(Sender: TObject);
    procedure btnDisconectAllClick(Sender: TObject);
    procedure btnFindContextClick(Sender: TObject);
    procedure btnGetWorkerStateClick(Sender: TObject);
    procedure btnPoolInfoClick(Sender: TObject);
    procedure btnPostWSACloseClick(Sender: TObject);
    procedure btnReOpenTestClick(Sender: TObject);
    procedure chkEchoClick(Sender: TObject);
    procedure chkLogDetailsClick(Sender: TObject);
    procedure chkSaveToFileClick(Sender: TObject);
    procedure chkShowInMemoClick(Sender: TObject);
    procedure chkUseBufferPoolClick(Sender: TObject);
    procedure tmrInfoTimer(Sender: TObject);
    procedure tmrKickOutTimer(Sender: TObject);
    procedure tmrTestTimer(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    //iCounter:Integer;
    FChkUseBufferPool:Boolean;
    FChkEcho:Boolean;
    FChkShowInMemo:Boolean;
    FChkSaveToFile:Boolean;
    FTcpServer: TDiocpTcpServer;
    FPool:PBufferPool;
    procedure ReadState;
    procedure RefreshState;
    procedure OnRecvBuffer(pvClientContext:TIocpClientContext; buf:Pointer;
        len:cardinal; errCode:Integer);
procedure OnSendBufferCompleted(pvContext: TIocpClientContext; pvBuff: Pointer;
        len: Cardinal; pvBufferTag, pvErrorCode: Integer);
procedure OnAccept(pvSocket: THandle; pvAddr: String; pvPort: Integer; var
        vAllowAccept: Boolean);
    procedure OnDisconnected(pvClientContext: TIocpClientContext);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public declarations }
  end;
var
  frmMain: TfrmMain;
  LoginGUID:TStringList;
implementation
uses
  uFMMonitor, diocp_core_engine, diocp_core_rawWinSocket,StrUtils;
{$R *.dfm}
constructor TfrmMain.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
sfLogger.setAppender(TStringsAppender.Create(mmoLog.Lines));
  sfLogger.AppendInMainThread := true;
FTcpServer := TDiocpTcpServer.Create(Self);
  FTcpServer.Name := 'iocpSVR';
  FTcpServer.OnDataReceived := self.OnRecvBuffer;
  FTcpServer.OnContextAccept := OnAccept;
  FTcpServer.createDataMonitor;
  FTcpServer.OnSendBufferCompleted := OnSendBufferCompleted;
  FTcpServer.OnContextDisconnected := OnDisconnected;
  FPool := NewBufferPool(FTcpServer.WSARecvBufferSize);
  TFMMonitor.createAsChild(pnlMonitor, FTcpServer);
  ReadState;
LoginGUID:=TStringList.Create;
end;
destructor TfrmMain.Destroy;
begin
  FTcpServer.SafeStop;
  FreeBufferPool(FPool);
  FTcpServer.Free;
  LoginGUID.Free;
  inherited Destroy;
end;
procedure TfrmMain.RefreshState;
begin
  if FTcpServer.Active then
  begin
    btnOpen.Action := actStop;
end else
  begin
    LoginGUID.Clear;
    btnOpen.Action := actOpen;
  end;
  chkUseContextPool.Enabled := not FTcpServer.Active;
  edtPort.Enabled := not FTcpServer.Active;
  edtThread.Enabled := not FTcpServer.Active;
end;
procedure TfrmMain.actOpenExecute(Sender: TObject);
begin
  FTcpServer.WorkerCount := StrToInt(edtThread.Text);
  FTcpServer.Port := StrToInt(edtPort.Text);
  FTcpServer.OnDataReceived := self.OnRecvBuffer;
  FTcpServer.UseObjectPool := chkUseContextPool.Checked;
  FTcpServer.Active := true;
  RefreshState;
end;
procedure TfrmMain.actPushToAllExecute(Sender: TObject);
var
  ansiStr:AnsiString;
var
  lvList:TList;
  i:Integer;
  lvContext:TIocpClientContext;
begin
  ansiStr := mmoPushData.Lines.Text;
  lvList := TList.Create;
  try
    FTcpServer.getOnlineContextList(lvList);
    for i:=0 to lvList.Count -1 do
    begin
      lvContext := TIocpClientContext(lvList[i]);
      lvContext.PostWSASendRequest(PAnsiChar(ansiStr), Length(ansiStr));
    end;
  finally
    lvList.Free;
  end;
end;
procedure TfrmMain.actStopExecute(Sender: TObject);
begin
  FTcpServer.DisconnectAll;
  FTcpServer.SafeStop;
  RefreshState;
end;
procedure TfrmMain.btn1Click(Sender: TObject);
begin
mmo2.Text:=LoginGUID.Text;
end;
procedure TfrmMain.btnDisconectAllClick(Sender: TObject);
begin
  FTcpServer.DisConnectAll();
end;
procedure TfrmMain.btnFindContextClick(Sender: TObject);
var
  lvList:TList;
  i:Integer;
begin
  lvList := TList.Create;
  try
    FTcpServer.getOnlineContextList(lvList);
    for i:=0 to lvList.Count -1 do
    begin
      FTcpServer.findContext(TIocpClientContext(lvList[i]).SocketHandle);
    end;
  finally
    lvList.Free;
  end;
end;
procedure TfrmMain.btnGetWorkerStateClick(Sender: TObject);
begin
  ShowMessage(FTcpServer.IocpEngine.getWorkerStateInfo(0));
end;
procedure TfrmMain.btnPoolInfoClick(Sender: TObject);
var
  s:string;
  r:Integer;
begin
  if FPool = nil then Exit;
  s :=Format('get:%d, put:%d, addRef:%d, releaseRef:%d, size:%d',
    [FPool.FGet, FPool.FPut, FPool.FAddRef, FPool.FReleaseRef, FPool.FSize]);
  r := CheckBufferBounds(FPool);
  s := s + sLineBreak + Format('池中共有:%d个内存块, 可能[%d]个内存块写入越界的情况', [FPool.FSize, r]);
  ShowMessage(s);
end;
procedure TfrmMain.btnPostWSACloseClick(Sender: TObject);
var
  lvList:TList;
  i:Integer;
begin
  lvList := TList.Create;
  try
    FTcpServer.getOnlineContextList(lvList);
    for i:=0 to lvList.Count -1 do
    begin
      TIocpClientContext(lvList[i]).PostWSACloseRequest();
    end;
  finally
    lvList.Free;
  end;
end;
procedure TfrmMain.btnReOpenTestClick(Sender: TObject);
begin
  FTcpServer.logMessage('DoHeartBeatChcek', 'DEBUG', lgvDebug);
  tmrTest.Enabled := not tmrTest.Enabled;
end;
procedure TfrmMain.chkLogDetailsClick(Sender: TObject);
begin
  if chkLogDetails.Checked then
  begin
    FTcpServer.Logger.LogFilter := LogAllLevels;
  end else
  begin
    FTcpServer.Logger.LogFilter := [lgvError];     // 只记录致命错误
  end;
end;
procedure TfrmMain.chkEchoClick(Sender: TObject);
begin
  ReadState;
end;
procedure TfrmMain.chkSaveToFileClick(Sender: TObject);
begin
  ReadState;
end;
procedure TfrmMain.chkShowInMemoClick(Sender: TObject);
begin
  ReadState;
end;
procedure TfrmMain.chkUseBufferPoolClick(Sender: TObject);
begin
  ReadState;
end;
procedure TfrmMain.OnAccept(pvSocket: THandle; pvAddr: String; pvPort: Integer;
    var vAllowAccept: Boolean);
begin
mmo1.Lines.Add(pvAddr+':'+inttostr(pvPort));
//  if pvAddr = '127.0.0.1' then
//    vAllowAccept := false;
end;
procedure TfrmMain.OnDisconnected(pvClientContext: TIocpClientContext);
begin
  if pvClientContext.Data <> nil then
  begin
    TObject(pvClientContext.Data).Free;
    pvClientContext.Data := nil;
  end;
end;
procedure TfrmMain.OnRecvBuffer(pvClientContext:TIocpClientContext;
    buf:Pointer; len:cardinal; errCode:Integer);
var
  j:Integer;
  s:AnsiString;
  lvBuff:PByte;
  lvFileWriter:TSingleFileWriter;
  sGUID:string;
  PostGUID:string;
begin
    if FChkShowInMemo then
    begin
      sGUID := CreateClassID;
      //   如果客户端发送的为字符串,可以用下面代码进行显示
      SetLength(s, len);
      Move(buf^, s[1], len);
      sfLogger.logMessage(s);
      if Pos('GUID',s)>0 then
      begin
      PostGUID:=midstr(s,6,38);
      if LoginGUID.IndexOf(PostGUID)<>-1 then
begin
pvClientContext.PostWSASendRequest( PAnsiChar('Success;GUID='+AnsiString(PostGUID)), Length('Success;GUID='+AnsiString(PostGUID)));
//这里可写其它的业务处理代码,就是一次交互数据等,客户端每次与服务器交互时都带上服务器分配的GUID做为身份名牌
end
else
      pvClientContext.PostWSASendRequest(PAnsiChar('Eerror'), Length('Eerror'));
      end
      else
      if s='stu=admin&pwd=admin123' then
      begin
      LoginGUID.Sorted:=True;
      LoginGUID.Duplicates := dupIgnore;
      LoginGUID.Add(sGUID);
      pvClientContext.PostWSASendRequest( PAnsiChar('Success;GUID='+AnsiString(sGUID)), Length('Success;GUID='+AnsiString(sGUID)));
end
      else
      begin
      pvClientContext.PostWSASendRequest(PAnsiChar('Eerror'), Length('Eerror'));
      pvClientContext.DoDisconnect;
      end;
end;
    if FChkEcho then
    begin
      if FChkUseBufferPool then
      begin
lvBuff := GetBuffer(FPool);
Move(buf^, lvBuff^, len);
//
        AddRef(lvBuff);
pvClientContext.PostWSASendRequest(lvBuff, len, dtNone, 1);
      end else
      begin
        pvClientContext.PostWSASendRequest(buf, len);
      end;
    end;
if FChkShowInMemo then
    begin
      lvFileWriter := TSingleFileWriter(pvClientContext.Data);
      if lvFileWriter = nil then
      begin
        lvFileWriter := TSingleFileWriter.Create;
        pvClientContext.Data := lvFileWriter;
        lvFileWriter.FilePreFix := Format('RECV_%d', [pvClientContext.SocketHandle]);
        lvFileWriter.FilePerSize := 1024 * 1024 * 100;
      end;
lvFileWriter.WriteBuffer(buf, len);
    end;
end;
procedure TfrmMain.OnSendBufferCompleted(pvContext: TIocpClientContext; pvBuff:
    Pointer; len: Cardinal; pvBufferTag, pvErrorCode: Integer);
begin
  if pvBufferTag = 1 then
    ReleaseRef(pvBuff);
end;
procedure TfrmMain.ReadState;
begin
  FChkEcho := chkEcho.Checked;
  FChkShowInMemo := chkShowInMemo.Checked;
  FChkUseBufferPool := chkUseBufferPool.Checked;
  FChkSaveToFile := chkSaveToFile.Checked;
end;
procedure TfrmMain.tmrInfoTimer(Sender: TObject);
begin
  self.Caption := Format('DIOCP 测试:%d, %d', [__DebugWSACreateCounter, __DebugWSACloseCounter]);
end;
procedure TfrmMain.tmrKickOutTimer(Sender: TObject);
begin
  FTcpServer.KickOut(30000);
end;
procedure TfrmMain.tmrTestTimer(Sender: TObject);
begin
  actStop.Execute;
Application.ProcessMessages;
actOpen.Execute;
end;
end.
DIOCP之DEMO-登陆验证设计(二)的更多相关文章
- WDA演练一:用户登陆界面设计(二)
		一,登陆界面设计: 1.将系统编号灰显,默认初值 2.密码栏勾选密码显示,这样就不会明文显示在页面上了: Init方法中添加默认值代码: METHOD wddoinit . DATA lo_nd_zh ... 
- Java的登陆验证问题
		java中的登陆验证问题可以有多种方式进行验证,通过拦截器功能完成,可以通过过滤器功能完成,也可以简单的代码在JSP页面中单独完成,其中都 涉及到一个关键的验证步骤,这个验证原理ASP,PHP,JAV ... 
- Shrio登陆验证实例详细解读(转)
		摘要:本文采用了Spring+SpringMVC+Mybatis+Shiro+Msql来写了一个登陆验证的实例,下面来看看过程吧!整个工程基于Mavevn来创建,运行环境为JDK1.6+WIN7+to ... 
- 【Java EE 学习 70 上】【数据采集系统第二天】【数据加密处理】【登陆验证】【登陆拦截器】【新建调查】【查询调查】
		一.数据加密处理 这里使用MD5加密处理,使用java中自带加密工具类MessageDigest. 该类有一个方法digest,该方法输入参数是一个字符串返回值是一个长度为16的字节数组.最关键的是需 ... 
- tornado web高级开发项目之抽屉官网的页面登陆验证、form验证、点赞、评论、文章分页处理、发送邮箱验证码、登陆验证码、注册、发布文章、上传图片
		本博文将一步步带领你实现抽屉官网的各种功能:包括登陆.注册.发送邮箱验证码.登陆验证码.页面登陆验证.发布文章.上传图片.form验证.点赞.评论.文章分页处理以及基于tornado的后端和ajax的 ... 
- 【Java EE 学习 20】【使用过滤器实现登陆验证、权限认证】【观察者模式和监听器(使用监听器实现统计在线IP、登录IP 、踢人功能)】
		一.使用过滤器实现登录验证.权限认证 1.创建5张表 /*使用过滤器实现权限过滤功能*/ /**创建数据库*/ DROP DATABASE day20; CREATE DATABASE day20; ... 
- Cookie、Session登陆验证相关介绍和用法
		一.Cookie和Session 首先.HTTP协议是无状态的:所谓的无状态是指每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应直接影响,也不会直接 ... 
- 1_python小程序之实现用户的注册登陆验证功能
		python小程序之实现用户的注册登陆验证功能 程序扼要简述: 一.程序流程:1.程序开始2.判断本地文件/数据库是否已存在用户信息,存在则跳转到登陆,否则跳转到注册,注册成功后后跳转到登陆3.判断 ... 
- flask之flask-login登陆验证(一)
		这个模块能帮助我们做很多事,最常用到的是,登陆验证(验证当前用户是否已经登陆).记住我功能 一 安装 pip install flask-login 二 导入相关模块及对象并初始化 from flas ... 
随机推荐
- 【 D3.js 入门系列 --- 1 】 第一个程序HelloWorld
			下面开始用D3.js处理第一个简单问题,先看下面的代码: <html> <head> <meta charset="utf-8"> <ti ... 
- iOS的URL处理
			前两天处理iOSapp过程中(我是用swift语言写的,资料较少),被一个“字符串”搞了一晚上的时间到第二天才处理好,在此记下,望见过此文的学生有一天遇到该情况能三分钟搞定不浪费时间: 先看如下代码 ... 
- SPOJ QTREE Query on a tree
			题意:给一颗n个点的树,有两种操作CHANGE i ti : 把第i条边的权变为tiQUERY a b : 问点a 到 点b 之间的边的最大权 思路:树剖处理边权.由于是边,所以只需要把边权处理到子节 ... 
- 使用seajs封装js模块
			//方法一:将函数绑定到原型上 define(function(require, exports, module) { $.fn.tab = function(option, callback) { ... 
- IE 11 保护模式害惨了我
			花了几乎两天,一直用IE, 就说好好的 动态域名 为什么一直不能访问.用其它浏览器一试,我哭了,都是好的. 
- 高效Web开发的10个jQuery代码片段(10 JQUERY SNIPPETS FOR EFFICIENT WEB DEVELOPMENT)
			在过去的几年中,jQuery一直是使用最为广泛的JavaScript脚本库.今天我们将为各位Web开发者提供10个最实用的jQuery代码片段,有需要的开发者可以保存起来. 1.检测Internet ... 
- Install Qt creator
			download qt for linux yum install dialog move download qt file(qt-opensource-linux-x64-5.6.0.run) fr ... 
- Redis介绍以及安装(Linux)
			Redis介绍以及安装(Linux) redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的 ... 
- 黄聪:如何关闭phpstorm的typo拼写检查
			文件-设置-编辑器-inspections-spelling-typo 
- (转)原始图像数据和PDF中的图像数据
			比较原始图像数据和PDF中的图像数据,结果见表1.1.表1.1中各种“解码器”的解释见本文后续的“PDF支持的图像格式”部分,“PDF中的图像数据”各栏中的数据来自开源的PdfView.如果您有兴趣查 ... 
