📄 mainsercli.pas
字号:
unit MainSerCli;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, Menus;
const
CMax=1000; //客户端最大连接数Gi<s:
type
session_record=record
Used: boolean; {会话记录是否可用}
SS_Handle: integer; {代理服务器套接字句柄}
CSocket: TClientSocket; {用于连接远程的套接字}
Lookingup: boolean; {是否正在查找服务器}
LookupTime: integer; {查找服务器时间}
Request: boolean; {是否有请求}
request_str: string; {请求数据块}
client_connected: boolean; {客户机联机标志}
remote_connected: boolean; {远程服务器连接标志}
end;
type
TMainSerCliFm = class(TForm)
Button2: TButton;
ServerSocket1: TServerSocket;
ClientSocket1: TClientSocket;
Button3: TButton;
MainMenu1: TMainMenu;
N1: TMenuItem;
N3: TMenuItem;
GroupBox1: TGroupBox;
Memo1: TMemo;
GroupBox2: TGroupBox;
Memo2: TMemo;
Button1: TButton;
Button4: TButton;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
procedure N3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button3Click(Sender: TObject);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
service_enabled: boolean; {代理服务是否开启}
sessions: integer; {会话数}
session:array[0..CMax] of session_record;
lookuptimeout: integer; {连接超时值}
invalidrequests: integer;
end;
var
MainSerCliFm: TMainSerCliFm;
implementation
uses SysInitFm, DataModuleFm;
{$R *.dfm}
procedure TMainSerCliFm.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j: integer;
begin
j:=-1;
for i:=1 to sessions do {查找是否有空白项}
if not session[i-1].Used and not session[i-1].CSocket.active then
begin
j:=i-1; {有,分配它}
session[j].Used:=true; {置为在用}
break;
end
else
if not session[i-1].Used and session[i-1].CSocket.active then
session[i-1].CSocket.active:=false;
if j=-1 then
begin {无,新增一个}
j:=sessions;
inc(sessions);
// setlength(session,sessions);
session[j].Used:=true; {置为在用}
session[j].CSocket:=TClientSocket.Create(nil);
session[j].CSocket.OnConnect:=ClientSocket1Connect;
session[j].CSocket.OnDisconnect:=ClientSocket1Disconnect;
session[j].CSocket.OnError:=ClientSocket1Error;
session[j].CSocket.OnRead:=ClientSocket1Read;
session[j].CSocket.OnWrite:=ClientSocket1Write;
session[j].Lookingup:=false;
end;
session[j].SS_Handle:=socket.socketHandle; {保存句柄,实现绑定}
session[j].Request:=false; {无请求}
session[j].client_connected:=true; {客户机已连接}
session[j].remote_connected:=false; {远程未连接}
edit1.Text:=inttostr(sessions);
end;
procedure TMainSerCliFm.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j,k: integer;
begin
for i:=1 to sessions do
if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
begin
session[i-1].client_connected:=false; {客户机未连接}
if session[i-1].remote_connected then
session[i-1].CSocket.active:=false {假如远程尚连接,断开它}
else
session[i-1].Used:=false; {假如两者都断开,则置释放资源标志}
break;
end;
j:=sessions;
k:=0;
for i:=1 to j do {统计会话数组尾部有几个未用项}
begin
if session[j-i].Used then
break;
inc(k);
end;
if k>0 then {修正会话数组,释放尾部未用项}
begin
sessions:=sessions-k;
// setlength(session,sessions);
end;
end;
procedure TMainSerCliFm.ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Text :='等待客户端连接...';
end;
procedure TMainSerCliFm.N3Click(Sender: TObject);
begin
SysInitForm.ShowModal();
end;
procedure TMainSerCliFm.Button1Click(Sender: TObject);
var
localport:String;
begin
localport:=DataModuleForm.ReadInifile('..\config\SYSINIT.ini','本地服务端口','PORT');
if localport='' then
begin
showmessage('本地服务端口未设置');
exit;
end;
ServerSocket1.Port:= strtoint(localport);
try
ServerSocket1.Open;
Memo1.Text:='启动服务端服务成功'
except
showmessage('启动服务端服务失败');
end;
end;
procedure TMainSerCliFm.Button4Click(Sender: TObject);
begin
try
ServerSocket1.Close;
ClientSocket1.Close;
Memo1.Text:='关闭服务端服务成功'
except
showmessage('关闭服务端服务失败');
end;
end;
procedure TMainSerCliFm.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
host,port: string;
i,j: integer;
begin
host:=DataModuleForm.ReadInifile('..\config\SYSINIT.ini','交通罚款中转服务器','IP');
if host='' then
begin
showmessage('交通罚款中转服务器IP地址未设置');
exit;
end;
port:=DataModuleForm.ReadInifile('..\config\SYSINIT.ini','交通罚款中转服务器','PORT');
if port='' then
begin
showmessage('交通罚款中转服务器端口未设置');
exit;
end;
for i:=1 to sessions do {判断是哪一个会话}
if session[i-1].Used and (session[i-1].SS_Handle=Socket.sockethandle) then
begin
session[i-1].request_str:=Socket.ReceiveText; {保存请求数据}
Memo1.Lines.Add(session[i-1].request_str);
if not session[i-1].remote_connected then {假如远征尚未连接}
begin
session[i-1].Request:=true; {置请求数据就绪标志}
session[i-1].CSocket.active:=false;
session[i-1].CSocket.Host:=host; {设置远程主机地址}
session[i-1].CSocket.Port:=strtoint(port); {设置端口}
session[i-1].CSocket.active:=true;
session[i-1].Lookingup:=true; {置标志}
session[i-1].LookupTime:=0; {从0开始计时}
end
else
session[i-1].CSocket.socket.sendtext(session[i-1].request_str);
end;
end;
procedure TMainSerCliFm.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
var
i: integer;
begin
for i:=1 to sessions do
if (session[i-1].CSocket.socket.sockethandle=socket.SocketHandle) and session[i-1].Used then
begin
session[i-1].CSocket.tag:=socket.SocketHandle;
session[i-1].remote_connected:=true; {置远程主机已连通标志}
session[i-1].Lookingup:=false; {清标志}
break;
end;
end;
procedure TMainSerCliFm.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j,k: integer;
begin
for i:=1 to sessions do
if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
begin
session[i-1].remote_connected:=false; {置为未连接}
if not session[i-1].client_connected then
session[i-1].Used:=false {假如客户机已断开,则置释放资源标志}
else
for k:=1 to serversocket1.Socket.ActiveConnections do
if (serversocket1.Socket.Connections[k-1].SocketHandle=session[i-1].SS_Handle) and session[i-1].used then
begin
serversocket1.Socket.Connections[k-1].Close;
break;
end;
break;
end;
j:=sessions;
k:=0;
for i:=1 to j do
begin
if session[j-i].Used then
break;
inc(k);
end;
if k>0 then
begin
sessions:=sessions-k;
// setlength(session,sessions);
end;
end;
procedure TMainSerCliFm.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
var
i: integer;
begin
for i:=1 to sessions do
if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
begin
if session[i-1].Request then
begin
socket.SendText(session[i-1].request_str); {假如有请求,发送}
session[i-1].Request:=false; {清标志}
end;
break;
end;
end;
procedure TMainSerCliFm.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j: integer;
rec_bytes: integer; {传回的数据块长度}
rec_Buffer: array[0..8193] of char; {传回的数据块缓冲区}
begin
FillChar(rec_Buffer,sizeof(rec_Buffer),0);
for i:=1 to sessions do
if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
begin
rec_bytes:=socket.ReceiveBuf(rec_buffer,8192); {接收数据}
for j:=1 to serversocket1.Socket.ActiveConnections do
if serversocket1.Socket.Connections[j-1].SocketHandle=session[i-1].SS_Handle then
begin
serversocket1.Socket.Connections[j-1].SendBuf(rec_buffer,rec_bytes); {发送数据}
Memo2.Lines.Add(rec_buffer);
break;
end;
break;
end;
end;
procedure TMainSerCliFm.Button3Click(Sender: TObject);
begin
ServerSocket1.Close;
ClientSocket1.Close;
MainSerCliFm.Close;
end;
procedure TMainSerCliFm.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
var
i,j,k: integer;
begin
for i:=1 to sessions do
if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
begin
session[i-1].client_connected:=false; {客户机未连接}
if session[i-1].remote_connected then
session[i-1].CSocket.active:=false {假如远程尚连接,断开它}
else
session[i-1].Used:=false; {假如两者都断开,则置释放资源标志}
break;
end;
j:=sessions;
k:=0;
for i:=1 to j do
begin
if session[j-i].Used then
break;
inc(k);
end;
if k>0 then
begin
sessions:=sessions-k;
// setlength(session,sessions);
end;
errorcode:=0;
end;
procedure TMainSerCliFm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
ServerSocket1.Close;
ClientSocket1.Close;
end;
procedure TMainSerCliFm.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
var
i,j,k: integer;
begin
for i:=1 to sessions do
if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
begin
session[i-1].client_connected:=false; {客户机未连接}
if session[i-1].remote_connected then
session[i-1].CSocket.active:=false {假如远程尚连接,断开它}
else
session[i-1].Used:=false; {假如两者都断开,则置释放资源标志}
break;
end;
j:=sessions;
k:=0;
for i:=1 to j do
begin
if session[j-i].Used then
break;
inc(k);
end;
if k>0 then
begin
sessions:=sessions-k;
// setlength(session,sessions);
end;
errorcode:=0;
end;
procedure TMainSerCliFm.FormActivate(Sender: TObject);
begin
sessions:=0;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -