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.

时间: 2024-10-12 16:28:13

DIOCP之DEMO-登陆验证设计(二)的相关文章

DIOCP之DEMO-登陆验证设计

登陆设计原理: (一)client在与服务器建立连接后向服务器发送含有"USER=XXXXX&PWD=XXXXX"或者用JSON字符串. client的代码需要写在OnContextConnected事件中,注{"cmd":"login","User":"admin","Pwd":"admin888"} (二)服务器收到客户端传来的命令串后,首先判断命令是不是

Shrio登陆验证实例详细解读

摘要:本文采用了Spring+SpringMVC+Mybatis+Shiro+Msql来写了一个登陆验证的实例,下面来看看过程吧!整个工程基于Mavevn来创建,运行环境为JDK1.6+WIN7+tomcat7. 这里主要说了Shiro的搭建过程,Spring+SpringMVC+Mybatis的搭建过可以看这里Spring+Mybatis+SpringMVC+Maven+MySql搭建实例 整个工程免费下载: 最终效果如下: 工程整体的目录如下: java代码如下: 配置文件如下: 页面资源如

Java的登陆验证问题

java中的登陆验证问题可以有多种方式进行验证,通过拦截器功能完成,可以通过过滤器功能完成,也可以简单的代码在JSP页面中单独完成,其中都 涉及到一个关键的验证步骤,这个验证原理ASP,PHP,JAVA等语言都大致相同,但具体到不同语言实现时有些差别:同时验证还涉及另外一个独立的问题 是验证到什么程度的问题,下面我就以我的认识讲解一下: 一,验证原理 下面看看JAVA中的验证关键步骤,一般我们用session变量来保存用户成功登录后的密码,为了防止用户把URL复制下来然后直接在浏览器地址 栏中输

【Java EE 学习第70天】【数据采集系统第二天】【数据加密处理】【登陆验证】【登陆拦截器】【新建调查】【查询调查】

一.数据加密处理 这里使用MD5加密处理,使用java中自带加密工具类MessageDigest. 该类有一个方法digest,该方法输入参数是一个字符串返回值是一个长度为16的字节数组.最关键的是需要将这个16位的字节数组转换成为32位的字符串,转换方法是使用位移+与运算.将高四位移到低四位&0X0F得到一个字符,直接使用该值&0X0F得到一个字符,这样一个8bit的字节就能够拆成2个字符.最终16Byte就能够转换成为32个字符. 1 package com.kdyzm.utils;

【java项目实战】Servlet详解以及Servlet编写登陆页面(二)

Servlet是Sun公司提供的一门用于开发动态web网页的技术.Sun公司在API中提供了一个servlet接口,我们如果想使用java程序开发一个动态的web网页,只需要实现servelet接口,并把类部署到web服务器上就可以运行了. 到底什么是Servlet呢? 通俗一点,只要是实现了servlet接口的java程序,均称Servlet.Servlet是由sun公司命名的,Servlet = Server + Applet(Applet表示小应用程序),Servlet是在服务器端运行的小

爬虫登陆验证过程

混合模式 结合二.三两大步,通过模拟点击快速拿到cookie,虽然效率低,但可以减少数据包分析的时间以及解决搞不定ajax登陆验证的烦恼,然后继续用urllib2拼接cookie继续快速获取数据.分下面两步: a. 从selenium中拿到cookie b. 添加cookie给urllib2使用 方法1:使用CookieJar,可参考<Creating Custom Cookies for HTTP Requests> 方法2:直接拼凑一个名称是"Cookie"的heade

【Java EE 学习第20 天】【使用过滤器实现登陆验证、权限认证】【观察者模式和监听器(使用监听器实现统计在线IP、登录IP 、踢人功能)】

一.使用过滤器实现登录验证.权限认证 1.创建5张表 /*使用过滤器实现权限过滤功能*/ /**创建数据库*/ DROP DATABASE day20; CREATE DATABASE day20; USE DAY20; /*用户表*/ DROP TABLE IF EXISTS USER; CREATE TABLE USER( userid VARCHAR(32) , username VARCHAR(32), userpassword VARCHAR(32), CONSTRAINT pk_us

登陆验证表单原理

22:25 2014/5/11 javaweb中表单登陆验证:表单验证原理都一样,不过struts2提供了validate方法. 没有Form表单类的登陆都是简单的登陆 1.通常把用户名密码为为不为空和用户名长度和密码长度写到Form表单类里通常叫做validate方法返回值为Map<String, String>类型 在LoginServlet里调用下就行,通常用webutils里的转换成bean方法得到Form类的对象,不用自己创建Form的实例更不用什么get/set那是stuts2的方

C#使用MVC框架实现登陆验证

步骤一:需求分析 我的目标是利用MVC框架实现简单登陆验证.从客户端输入用户名和密码.然后传给数据库验证.如果数据库存在此用户名ID和密码,则返回客户端账户姓名的成功提示.否则返回客户端失败信息. 步骤二:搭建MVC框架 新建项目>WEB>WEB应用程序 步骤三:先添加一个控制器,然后VIEWS文件夹下找到对应和控制器同名文件夹里面搭建VIEW界面样式,最后修改路由 确定能在浏览器访问 控制器: public class LoginController : Controller    {