主要是同时下线的问题,同时下线时出错,无法发出下线的命令,我知道问题是出在将pclient设为全局变量上,但我用了,EnterCriticalSection(cs);LeaveCriticalSection(cs)了,怎么还不行呢?(我知道VCL是非安全的,在我的完整程序里有考虑到了,这个不是主要的问题)Private
pclient:array of Rclientdata;
{ Private declarations }
public cs: TRTLCriticalSection;
{ Public declarations }
end;var
Main: TMain;
implementation{$R *.dfm}
procedure TMain.FormShow(Sender: TObject);
begin
idtcpserver1.Active:=true;
dm.ADOConnection1.Connected:=true;
dm.userQuery.Active:=true;
dm.machineQuery.Active:=true;
InitializeCriticalSection(cs);
rzrichedit3.Lines.Add('服务器已激活,欢迎使用本软件');
end;procedure TMain.IdTCPServer1Execute(AThread: TIdPeerThread);
var
msg:RmessageData;
rec,rec1,rec2,rec3,rec4,rec5:RrectiveData;i:integer;
begin
if not athread.Terminated then
begin
athread.Connection.ReadBuffer(msg,sizeof(msg));
EnterCriticalSection(cs);
try
case msg.command of
clogin:
begin with listbox1 do
if items.IndexOf(msg.userName)>-1 then
begin rec3.command:=cloginError;
athread.Connection.WriteBuffer(rec3,sizeof(rec3));
end
else
begin
dm.userQuery.Close;
dm.userQuery.SQL.Clear;
dm.userQuery.SQL.Add('select * from userMessage where Name= "'+msg.userName+ '" and Password= "'+msg.password+'"');
dm.userQuery.Open;
if not dm.userQuery.Eof then //将登录信息写入数据库
begin
dm.machineQuery.Append;
dm.machineQuery.FieldByName('UserName').AsString:=msg.userName;
dm.machineQuery.FieldByName('IP').AsString:=msg.IP;
dm.machineQuery.FieldByName('Port').AsString:=msg.port;
dm.machineQuery.FieldByName('StartTime').AsDateTime:=now();
dm.machineQuery.Post; rec.command:=cloginOK;
rec.userName:=msg.userName;
athread.Connection.WriteBuffer(rec,sizeof(rec)); for i:=0 to high(pclient) do
begin
rec1.command:=cuserList;
rec1.userName:=pclient[i].username;
rec2.command:=cuserList;
rec2.userName:=msg.userName;
pclient[i].thread.Connection.WriteBuffer(rec2,sizeof(rec2));
athread.Connection.WriteBuffer(rec1,sizeof(rec1));
end;
setlength(pclient,high(pclient)+2);
pclient[high(pclient)].username:=msg.userName;
pclient[high(pclient)].thread:=athread; Items.Add(msg.userName);
rzrichedit3.Lines.Add('用户 '+msg.userName+' 上线了'); end
else
begin
rec3.command:=cloginError;
athread.Connection.WriteBuffer(rec3,sizeof(rec3));
end;
end; //end; end;
coffOnline:
begin for i:= high(pclient) downto 0 do
begin
if pclient[i].username=msg.userName then
begin
pclient[i]:=pclient[high(pclient)];
setlength(pclient,high(pclient));
//break;
end;
end;
for i:=high(pclient) downto 0 do
begin
rec5.command:=cdeleOnline;
rec5.userName:=msg.userName;
pclient[i].thread.Connection.WriteBuffer(rec5,sizeof(rec5));
rzrichedit1.Lines.Add(pclient[i].username);
end;
with listbox1.items do
if IndexOf(msg.userName)>-1 then
begin
Delete(IndexOf(msg.userName));
end;
rzrichedit3.Lines.Add('用户 '+' '+msg.userName+' 下线了') ; end; end;
finally
LeaveCriticalSection(cs);
end;
end;
end;end.
主要是同时下线的问题,同时下线时出错,无法发出下线的命令,我知道问题是出在将pclient设为全局变量上,但我用了,EnterCriticalSection(cs);LeaveCriticalSection(cs)了,怎么还不行呢?(我知道VCL是非安全的,在我的完整程序里有考虑到了,这个不是主要的问题)
说明
pclient:array of Rclientdata;RclientData=record
username:string[20];
thread:TIdPeerThread;
pclient:array of Rclientdata;
{ Private declarations }
public cs: TRTLCriticalSection;
{ Public declarations }
end;var
Main: TMain;
implementation{$R *.dfm}
procedure TMain.FormShow(Sender: TObject);
begin
idtcpserver1.Active:=true;
dm.ADOConnection1.Connected:=true;
dm.userQuery.Active:=true;
dm.machineQuery.Active:=true;
InitializeCriticalSection(cs);
rzrichedit3.Lines.Add('服务器已激活,欢迎使用本软件');
end;procedure TMain.IdTCPServer1Execute(AThread: TIdPeerThread);
var
msg:RmessageData;
rec,rec1,rec2,rec3,rec4,rec5:RrectiveData;i:integer;
begin
if not athread.Terminated then
begin
athread.Connection.ReadBuffer(msg,sizeof(msg));
EnterCriticalSection(cs);
try
case msg.command of
clogin:
begin with listbox1 do
if items.IndexOf(msg.userName)>-1 then
begin rec3.command:=cloginError;
athread.Connection.WriteBuffer(rec3,sizeof(rec3));
end
else
begin
dm.userQuery.Close;
dm.userQuery.SQL.Clear;
dm.userQuery.SQL.Add('select * from userMessage where Name= "'+msg.userName+ '" and Password= "'+msg.password+'"');
dm.userQuery.Open;
if not dm.userQuery.Eof then //将登录信息写入数据库
begin
dm.machineQuery.Append;
dm.machineQuery.FieldByName('UserName').AsString:=msg.userName;
dm.machineQuery.FieldByName('IP').AsString:=msg.IP;
dm.machineQuery.FieldByName('Port').AsString:=msg.port;
dm.machineQuery.FieldByName('StartTime').AsDateTime:=now();
dm.machineQuery.Post; rec.command:=cloginOK;
rec.userName:=msg.userName;
athread.Connection.WriteBuffer(rec,sizeof(rec)); for i:=0 to high(pclient) do
begin
rec1.command:=cuserList;
rec1.userName:=pclient[i].username;
rec2.command:=cuserList;
rec2.userName:=msg.userName;
pclient[i].thread.Connection.WriteBuffer(rec2,sizeof(rec2));
athread.Connection.WriteBuffer(rec1,sizeof(rec1));
end;
setlength(pclient,high(pclient)+2);
pclient[high(pclient)].username:=msg.userName;
pclient[high(pclient)].thread:=athread; Items.Add(msg.userName);
rzrichedit3.Lines.Add('用户 '+msg.userName+' 上线了'); end
else
begin
rec3.command:=cloginError;
athread.Connection.WriteBuffer(rec3,sizeof(rec3));
end;
end; //end; end;
coffOnline:
begin for i:= high(pclient) downto 0 do
begin
if pclient[i].username=msg.userName then
begin
pclient[i]:=pclient[high(pclient)];
setlength(pclient,high(pclient));
//break;
end;
end;
for i:=high(pclient) downto 0 do
begin
rec5.command:=cdeleOnline;
rec5.userName:=msg.userName;
pclient[i].thread.Connection.WriteBuffer(rec5,sizeof(rec5));
rzrichedit1.Lines.Add(pclient[i].username);
end;
with listbox1.items do
if IndexOf(msg.userName)>-1 then
begin
Delete(IndexOf(msg.userName));
end;
rzrichedit3.Lines.Add('用户 '+' '+msg.userName+' 下线了') ; end; end;
finally
LeaveCriticalSection(cs);
end;
end;
end;end.
主要是同时下线的问题,同时下线时出错,无法发出下线的命令,我知道问题是出在将pclient设为全局变量上,但我用了,EnterCriticalSection(cs);LeaveCriticalSection(cs)了,怎么还不行呢?(我知道VCL是非安全的,在我的完整程序里有考虑到了,这个不是主要的问题)
说明
pclient:array of Rclientdata;RclientData=record
username:string[20];
thread:TIdPeerThread;
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货