我的服务器有 4 个 TCP 连接的客户端列表。如果列表已满,下一个客户必须拒绝
//服务器端
unit ServerUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdThreadMgr, IdThreadMgrDefault, IdAntiFreezeBase, IdAntiFreeze,
IdUDPBase, IdUDPServer, IdBaseComponent, IdComponent, IdTCPServer,
StdCtrls, ExtCtrls,IdSocketHandle, ComCtrls, IdUDPClient, Grids,
IdTCPConnection, IdTCPClient;
type
TForm1 = class(TForm)
Panel1: TPanel;
Label3: TLabel;
Edit3: TEdit;
Button1: TButton;
IdTCPServer1: TIdTCPServer;
IdUDPServer1: TIdUDPServer;
IdAntiFreeze1: TIdAntiFreeze;
IdThreadMgrDefault1: TIdThreadMgrDefault;
StatusBar1: TStatusBar;
GroupBox2: TGroupBox;
IncomingText: TMemo;
GroupBox1: TGroupBox;
Clients_StringGrid: TStringGrid;
IdTCPClient1: TIdTCPClient;
procedure Button1Click(Sender: TObject);
procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure ADDTCPConn(AThread: TIdPeerThread;i:Integer);
procedure DeleteRow1(VGrid: TStringGrid; VRow: integer);
procedure InsertRow1(VGrid: TStringGrid; Str1:String; Str2:String; Str3:String);
Procedure Add_To_StringGrid(Grid:TStringGrid; Str1:String; Str2:String; Str3:String; i:Integer);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
RCount:Integer;
flag:Boolean;
IPList : TStringList;
IPList2 : TStringList;
fl: Boolean;
implementation
uses CommonUnit;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if not IdUDPServer1.Active then
begin
IdUDPServer1.DefaultPort:=1717;
IdUDPServer1.BroadcastEnabled:=True;
IdUDPServer1.Active:=True;
end;
if not IdTCPServer1.Active then
begin
IdTCPServer1.DefaultPort:=1717;
IdTCPServer1.Active:=True;
end;
end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
s : String;
ip : String;
dss : TStringStream;
begin
try
dss := TStringStream.Create('');
dss.CopyFrom(AData, AData.Size);
s := dss.DataString;
ip:=GetIPAddress();
IncomingText.Lines.Add('Client Say('+ABinding.PeerIP+'):'+s);
IncomingText.Lines.Add('------------');
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, ip[1], Length(ip));
dss.Free();
except
on E : Exception do
WriteLogFile(E.message);
end;
end;
procedure TForm1.ADDTCPConn(AThread: TIdPeerThread;i:Integer);
var
NewClientIP : String;
begin
NewClientIP := AThread.Connection.Socket.Binding.PeerIP;
//NewClientHostName := IPAddrToName(NewClientIP);
//Add_To_StringGrid(Clients_StringGrid,NewClientIP,'ggg','eee',i);
InsertRow1(Clients_StringGrid,NewClientIP,'ggg','eee');
IncomingText.Lines.Add(TimeToStr(Time)+' Connection from "' + 'ggg' + '" on ' + NewClientIP);
IncomingText.Lines.Add('------------');
StatusBar1.Panels.Items[0].Text := ' Status : TCP Connected';
flag:=true;
end;
Procedure TForm1.Add_To_StringGrid(Grid:TStringGrid; Str1:String; Str2:String; Str3:String;
i:Integer);
Begin
if i=-1 then
begin
if RCount <> 0 then
Grid.RowCount := Grid.RowCount + 1;
RCount:=RCount+1;
Grid.Cells[0,RCount] := Str1;
Grid.Cells[1,RCount] := Str2;
Grid.Cells[2,RCount] := Str3;
end
else
begin
Grid.Cells[0,i] := Str1;
Grid.Cells[1,i] := Str2;
Grid.Cells[2,i] := Str3;
end;
End;
procedure TForm1.InsertRow1(VGrid: TStringGrid; Str1:String; Str2:String; Str3:String);
begin
if RCount<>0 then
VGrid.RowCount:= VGrid.RowCount + 1;
VGrid.Cells[0, VGrid.RowCount - 1]:= Str1;
VGrid.Cells[1, VGrid.RowCount - 1]:= Str2;
VGrid.Cells[2, VGrid.RowCount - 1]:= Str3;
RCount:=RCount+1;
end;
procedure TForm1.DeleteRow1(VGrid: TStringGrid; VRow: integer);
var
I, J: Integer;
begin
if VGrid.RowCount = 2 then
begin
VGrid.Rows[1].CommaText:= '"","","","",""';
end
else
begin
for I:= VRow to VGrid.RowCount - 2 do
for J:=0 to VGrid.ColCount - 1 do
VGrid.Cells[J,I]:= VGrid.Cells[J, I + 1];
VGrid.RowCount:= VGrid.RowCount - 1;
end;
RCount:=RCount-1;
if RCount=0 then
VGrid.RowCount:= 2;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RCount:=0;
Clients_StringGrid.Cells[0, 0]:= 'Client IP';
Clients_StringGrid.Cells[1, 0]:= 'Host Name';
Clients_StringGrid.Cells[2, 0]:= 'Versa';
end;
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
if flag then
AThread.Connection.WriteLn('Reply')
else
AThread.Connection.WriteLn('Reject');
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var
j:Integer;
fl:Boolean;
IP:String;
IPList2 : TStringList;
Count:Integer;
i:Integer;
begin
try
Count:=StrToInt(Edit3.Text);
IP:= AThread.Connection.Socket.Binding.PeerIP;
if (Clients_StringGrid.Cols[0].IndexOf(IP) = -1) then
begin
if RCount < Count then
begin
if (Clients_StringGrid.Cols[0].IndexOf(IP) = -1) then
ADDTCPConn(AThread,-1)
else
begin
StatusBar1.Panels.Items[0].Text := ' Status : TCP Already Connected';
flag:=True;
end;
end
else
begin
IPList:=TStringList.Create;
IPList2:=TStringList.Create;
fl:=False;
IPList.Clear;
IPList2.Clear;
For i:=1 To Count Do
begin
IdTCPClient1.Host := Clients_StringGrid.Cells[0,i];
IdTCPClient1.Port := 1112;
if IdTCPClient1.connected then
IdTCPClient1.Disconnect;
try
IdTCPClient1.Connect();
IdTCPClient1.Disconnect;
IPList.Add(Clients_StringGrid.Cells[0,i]);
except
on E : Exception do
begin
IPList2.Add(Clients_StringGrid.Cells[0,i]);
fl:=True;
end;
end;
end;
IncomingText.Lines.Add('Num Act ip:'+IntToStr(IPList.Count));
For j:=1 To IPList2.Count Do
begin
IncomingText.Lines.Add('row Del'+IntToStr(Clients_StringGrid.Cols[0].IndexOf(IPList2[j-1])));
DeleteRow1(Clients_StringGrid,Clients_StringGrid.Cols[0].IndexOf(IPList2[j-1]));
end;
if fl then
begin
ADDTCPConn(AThread,-1);
flag:=True;
end
else
flag:=false;
IPList.Free;
IPList2.Free;
end;
end
else
begin
StatusBar1.Panels.Items[0].Text := ' Status : TCP Already Connected';
flag:=True;
end;
except
on E : Exception do
WriteLogFile(E.message);
end;
end;
end.
//客户端
unit ClientUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, IdAntiFreezeBase, IdAntiFreeze,
IdTCPConnection, IdTCPClient, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient, ComCtrls, IdUDPServer,IdSocketHandle,IdStack, IdTCPServer,
IdThreadMgr, IdThreadMgrDefault;
type
TForm2 = class(TForm)
Panel1: TPanel;
Label3: TLabel;
Edit3: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
StatusBar1: TStatusBar;
GroupBox2: TGroupBox;
IncomingText: TMemo;
IdUDPClient1: TIdUDPClient;
IdTCPClient1: TIdTCPClient;
IdAntiFreeze1: TIdAntiFreeze;
IdTCPServer1: TIdTCPServer;
IdThreadMgrDefault1: TIdThreadMgrDefault;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
ServerIP:String;
implementation
uses CommonUnit;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
if not IdUDPClient1.Active then
begin
IdUDPClient1.Port:=1717;
IdUDPClient1.BroadcastEnabled:=True;
IdUDPClient1.Active:=True;
IdTCPServer1.Active:=False;
end;
Button1.Enabled:=False;
Button2.Enabled:=True;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
StrIn : String;
StrOut : String;
begin
try
StrOut:='Request';
IdUDPClient1.Broadcast(StrOut, 1717);
StrIn := IdUDPClient1.ReceiveString(100);
if not (StrIn='') then
begin
Button3.Enabled:=True;
Button2.Enabled:=False;
IncomingText.Lines.Add('UDP Reply');
StatusBar1.Panels.Items[0].Text := 'Status : UDP Connected';
ServerIP := StrIn;
end
else
WriteLogFile('UDP Connection Failed');
except
on E : Exception do
WriteLogFile(E.Message);
end;
end;
procedure TForm2.Button3Click(Sender: TObject);
var
StrIn : String;
begin
try
if ServerIP<>'' then
begin
IdTCPClient1.Host := ServerIP ;
IdTCPClient1.Port := 1717 ;
IdTCPClient1.Connect;
StrIn:= IdTCPClient1.ReadLn();
//IdTCPClient1.Disconnect;
if StrIn<>'' then
begin
IncomingText.Lines.Add(StrIn);
if StrIn<>'Reply' then
StatusBar1.Panels.Items[0].Text :='Connected To TCPServer';
else
begin
Button3.Enabled:=False;
Button1.Enabled:=True;
end;
end
else
WriteLogFile('TCP Connection Failed');
end;
except
on E : Exception do
WriteLogFile(E.message);
end;
end;
procedure TForm2.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
//check point
end;
end.
//当服务器上的 onconnect 事件想要检查列表中的客户端时,行 IdTCPClient1.Connect() 返回错误 1)Socket Error #10022 Invalid argument。2)连接优雅关闭。
并且永远不要在客户端运行 onexcute 为什么会这样