📄 main.pas
字号:
//DB 都没搞懂 我要了也没用 王清 QQ286251099 2008.3.23
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, WinSock, ExtCtrls, ComCtrls, Menus,
IniFiles, GateShare,
D7ScktComp, jpeg;
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)
ServerSocket: TServerSocket;
MemoLog: TMemo;
SendTimer: TTimer;
ClientSocket: TClientSocket;
Timer: TTimer;
DecodeTimer: TTimer;
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;
Panel1: TPanel;
Image1: TImage;
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);
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('CC攻击连接: ' + sRemoteIPaddr, 5);
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;
function isOkStr(Str:String):Boolean;
var
i:integer;
Begin
result:=True;
for i:=1 to Length(str) do
Begin
if ((Ord(Str[i])<$30)and(not (str[i] in ['#','0'..'9','!'])))or(ord(str[i])>128) then
Begin
Result:=False;
Exit;
End;
End;
End;
procedure TFrmMain.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
UserSession : pTUserSession;
nSockIndex : Integer;
sReviceMsg, s10, s1C: string;
nPos : Integer;
nMsgLen : Integer;
IPaddr : pTSockaddr;
sRemoteIPaddr : string;
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('HTTP/', sReviceMsg);
if npos>0 then
Begin
sRemoteIPaddr := UserSession.sRemoteIPaddr;
UserSession.Socket.Close;
New(IPaddr);
IPaddr.nIPaddr := inet_addr(PChar(sRemoteIPaddr));
BlockIPList.Add(IPaddr);
CloseConnect(sRemoteIPaddr);
exit;
end;
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;
if isOkStr(sReviceMsg) then
ClientSocket.Socket.SendText('%A' + IntToStr(Socket.SocketHandle) +'/' +sReviceMsg +'$')
else
Socket.Close;
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -