📄 main.pas
字号:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Menus, ExtCtrls, ComCtrls, JSocket, WinSock, IniFiles, GateShare;
const
GATEMAXSESSION = 10000;
type
TUserSession = record
Socket :TCustomWinSocket; //0x00
sRemoteIPaddr :String; //0x04
nSendMsgLen :Integer; //0x08
bo0C :Boolean; //0x0C
dw10Tick :LongWord; //0x10
nCheckSendLength :Integer; //0x14
boSendAvailable :Boolean; //0x18
boSendCheck :Boolean; //0x19
dwSendLockTimeOut :LongWord; //0x1C
n20 :Integer; //0x20
dwUserTimeOutTick :LongWord; //0x24
SocketHandle :Integer; //0x28
sIP :String; //0x2C
MsgList :TStringList; //0x30
dwConnctCheckTick :LongWord; //连接数据传输空闲超时检测
end;
pTUserSession = ^TUserSession;
TSessionArray = array [0..GATEMAXSESSION - 1] of TUserSession;
TFrmMain=class(TForm)
MemoLog: TMemo;
SendTimer: TTimer;
ClientSocket: TClientSocket;
Panel: TPanel;
Timer: TTimer;
DecodeTimer: TTimer;
LbHold: TLabel;
LbLack: TLabel;
Label2: TLabel;
StatusBar: TStatusBar;
MainMenu: TMainMenu;
MENU_CONTROL: TMenuItem;
StartTimer: TTimer;
MENU_CONTROL_START: TMenuItem;
MENU_CONTROL_STOP: TMenuItem;
MENU_CONTROL_RECONNECT: TMenuItem;
MENU_CONTROL_CLEAELOG: TMenuItem;
MENU_CONTROL_EXIT: TMenuItem;
MENU_VIEW: TMenuItem;
MENU_VIEW_LOGMSG: TMenuItem;
MENU_OPTION: TMenuItem;
MENU_OPTION_GENERAL: TMenuItem;
MENU_OPTION_IPFILTER: TMenuItem;
ServerSocket: TServerSocket;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
procedure MemoLogChange(Sender : TObject);
procedure FormDestroy(Sender : TObject);
procedure SendTimerTimer(Sender : TObject);
procedure TimerTimer(Sender : TObject);
procedure DecodeTimerTimer(Sender : TObject);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure StartTimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure MENU_CONTROL_STARTClick(Sender: TObject);
procedure MENU_CONTROL_STOPClick(Sender: TObject);
procedure MENU_CONTROL_RECONNECTClick(Sender: TObject);
procedure MENU_CONTROL_CLEAELOGClick(Sender: TObject);
procedure MENU_CONTROL_EXITClick(Sender: TObject);
procedure MENU_VIEW_LOGMSGClick(Sender: TObject);
procedure MENU_OPTION_GENERALClick(Sender: TObject);
procedure MENU_OPTION_IPFILTERClick(Sender: TObject);
procedure N4Click(Sender: TObject);
private
dwShowMainLogTick :LongWord;
boShowLocked :Boolean;
TempLogList :TStringList;
nSessionCount :Integer;
StringList30C :TStringList;
dwSendKeepAliveTick :LongWord;
boServerReady :Boolean;
StringList318 :TStringList;
dwDecodeMsgTime :LongWord;
dwReConnectServerTick:LongWord;
procedure ResUserSessionArray();
procedure StartService();
procedure StopService();
procedure LoadConfig();
procedure ShowLogMsg(boFlag: Boolean);
function IsBlockIP(sIPaddr: String): Boolean;
function IsConnLimited(sIPaddr: String): Boolean;
procedure CloseSocket(nSocketHandle:Integer);
function SendUserMsg(UserSession:pTUserSession;sSendMsg:String):Integer;
procedure ShowMainLogMsg;
procedure IniUserSessionArray;
{ Private declarations }
public
procedure CloseConnect(sIPaddr: String);
procedure MyMessage(var MsgData:TWmCopyData);message WM_COPYDATA;
{ Public declarations }
end ;
procedure MainOutMessage(sMsg:String;nMsgLevel:Integer);
var
FrmMain: TFrmMain;
g_SessionArray :TSessionArray;
ClientSockeMsgList :TStringList;
sProcMsg :String;
implementation
uses HUtil32, GeneralConfig, IPaddrFilter, Grobal2;
{$R *.DFM}
procedure MainOutMessage(sMsg:String;nMsgLevel:Integer);
var
tMsg:String;
begin
try
CS_MainLog.Enter;
if nMsgLevel <= nShowLogLevel then begin
tMsg:='[' + TimeToStr(Now) + '] ' + sMsg;
MainLogMsgList.Add(tMsg);
end;
finally
CS_MainLog.Leave;
end;
end;
procedure TFrmMain.ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
UserSession:pTUserSession;
sRemoteIPaddr,sLocalIPaddr:String;
nSockIndex:Integer;
IPaddr :pTSockaddr;
begin
Socket.nIndex:=-1;
sRemoteIPaddr:=Socket.RemoteAddress;
if g_boDynamicIPDisMode then begin
sLocalIPaddr:=ClientSocket.Socket.RemoteAddress;
end else begin
sLocalIPaddr:=Socket.LocalAddress;
end;
if IsBlockIP(sRemoteIPaddr) then begin
MainOutMessage('过滤连接: ' + sRemoteIPaddr,1);
Socket.Close;
exit;
end;
if IsConnLimited(sRemoteIPaddr) then begin
case BlockMethod of
mDisconnect: begin
Socket.Close;
end;
mBlock: begin
New(IPaddr);
IPaddr.nIPaddr:=inet_addr(PChar(sRemoteIPaddr));
TempBlockIPList.Add(IPaddr);
CloseConnect(sRemoteIPaddr);
end;
mBlockList: begin
New(IPaddr);
IPaddr.nIPaddr:=inet_addr(PChar(sRemoteIPaddr));
BlockIPList.Add(IPaddr);
CloseConnect(sRemoteIPaddr);
end;
end;
MainOutMessage('端口攻击: ' + sRemoteIPaddr,1);
exit;
end;
if boGateReady then begin
for nSockIndex:= 0 to GATEMAXSESSION - 1 do begin
UserSession:=@g_SessionArray[nSockIndex];
if UserSession.Socket = nil then begin
UserSession.Socket:=Socket;
UserSession.sRemoteIPaddr:=sRemoteIPaddr;
UserSession.nSendMsgLen:=0;
UserSession.bo0C:=False;
UserSession.dw10Tick:=GetTickCount();
UserSession.dwConnctCheckTick:=GetTickCount();
UserSession.boSendAvailable:=True;
UserSession.boSendCheck:=False;
UserSession.nCheckSendLength:=0;
UserSession.n20:=0;
UserSession.dwUserTimeOutTick:=GetTickCount();
UserSession.SocketHandle:=Socket.SocketHandle;
UserSession.sIP:=sRemoteIPaddr;
UserSession.MsgList.Clear;
Socket.nIndex:=nSockIndex;
Inc(nSessionCount);
break;
end;
end;
if Socket.nIndex >= 0 then begin
ClientSocket.Socket.SendText('%O' +
IntToStr(Socket.SocketHandle) +
'/' +
sRemoteIPaddr +
'/' +
sLocalIPaddr +
'$');
MainOutMessage('Connect: ' + sRemoteIPaddr,5);
end else begin
Socket.Close;
MainOutMessage('Kick Off: ' + sRemoteIPaddr,1);
end;
end else begin //0x004529EF
Socket.Close;
MainOutMessage('Kick Off: ' + sRemoteIPaddr,1);
end;
end;
procedure TFrmMain.ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
I:Integer;
UserSession:pTUserSession;
nSockIndex:Integer;
sRemoteIPaddr:String;
IPaddr :pTSockaddr;
nIPaddr :Integer;
begin
sRemoteIPaddr:=Socket.RemoteAddress;
nIPaddr:=inet_addr(PChar(sRemoteIPaddr));
nSockIndex:=Socket.nIndex;
for I := 0 to CurrIPaddrList.Count - 1 do begin
IPaddr:=CurrIPaddrList.Items[I];
if IPaddr.nIPaddr = nIPaddr then begin
Dec(IPaddr.nCount);
if IPaddr.nCount <= 0 then begin
Dispose(IPaddr);
CurrIPaddrList.Delete(I);
end;
Break;
end;
end;
if (nSockIndex >= 0) and (nSockIndex < GATEMAXSESSION) then begin
UserSession:=@g_SessionArray[nSockIndex];
UserSession.Socket:=nil;
UserSession.sRemoteIPaddr:='';
UserSession.SocketHandle:=-1;
UserSession.MsgList.Clear;
Dec(nSessionCount);
if boGateReady then begin
ClientSocket.Socket.SendText('%X' +
IntToStr(Socket.SocketHandle) +
'$');
MainOutMessage('DisConnect: ' + sRemoteIPaddr,5);
end;
end;
end;
procedure TFrmMain.ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
StringList30C.Add('Error ' + IntToStr(ErrorCode) + ': ' + Socket.RemoteAddress);
Socket.Close;
ErrorCode:=0;
end;
procedure TFrmMain.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
UserSession:pTUserSession;
nSockIndex:Integer;
sReviceMsg,s10,s1C:String;
nPos:Integer;
nMsgLen:Integer;
begin
nSockIndex:=Socket.nIndex;
if (nSockIndex >= 0) and (nSockIndex < GATEMAXSESSION) then begin
UserSession:=@g_SessionArray[nSockIndex];
sReviceMsg:=Socket.ReceiveText;
if (sReviceMsg <> '') and (boServerReady) then begin
nPos:=Pos('*',sReviceMsg);
if nPos > 0 then begin
UserSession.boSendAvailable:=True;
UserSession.boSendCheck:=False;
UserSession.nCheckSendLength:=0;
s10:=Copy(sReviceMsg,1,nPos -1);
s1C:=Copy(sReviceMsg,nPos + 1,Length(sReviceMsg) - nPos);
sReviceMsg:=s10 + s1C;
end;
nMsgLen:=length(sReviceMsg);
if (sReviceMsg <> '') and (boGateReady) and (not boKeepAliveTimcOut)then begin
UserSession.dwConnctCheckTick:=GetTickCount();
if (GetTickCount - UserSession.dwUserTimeOutTick) < 1000 then begin
Inc(UserSession.n20,nMsgLen);
end else UserSession.n20:= nMsgLen;
ClientSocket.Socket.SendText('%A' +
IntToStr(Socket.SocketHandle) +
'/' +
sReviceMsg +
'$');
end;
end;
end;
end;
procedure TFrmMain.MemoLogChange(Sender : TObject);
begin
if MemoLog.Lines.Count > 200 then MemoLog.Clear;
end;
procedure TFrmMain.FormDestroy(Sender : TObject);
var
nIndex:Integer;
begin
StringList30C.Free;
TempLogList.Free;
for nIndex:= 0 to GATEMAXSESSION - 1 do begin
g_SessionArray[nIndex].MsgList.Free;
end;
end;
procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if boClose then exit;
if Application.MessageBox('是否确认退出服务器?',
'提示信息',
MB_YESNO + MB_ICONQUESTION ) = IDYES then begin
if boServiceStart then begin
StartTimer.Enabled:=True;
CanClose:=False;
end;
end else CanClose:=False;
end;
procedure TFrmMain.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
boGateReady := True;
nSessionCount := 0;
dwKeepAliveTick := GetTickCount();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -