以下是IdTCPServerConnect事件登录部分的代码。 当客户端达到大约20时,新的客户端试图登录时,新的客户端显示“connection closed gracefully”, 但服务器仍然可以对已登录的客户进行服务,但服务器这时不能正常关闭,试图关闭服务器,显示: “Accessviolation at address 00408904 in module ‘Server.exe’.Read of address 00000000. procedure TFormServer.IdTCPServerConnect (AContext: TIdContext);” var Client: TUser; AUserName, Password: string; FirstReceiveString: string; lst: TList; i: integer; function ReadUserName(LoginName:string):Boolean; var ADOQuery: TADOQuery; MyString: string; begin Lock; try CoInitialize(nil); ADOQuery := TADOQuery.Create(nil); ForceConnectedToDatabase(true); try try Result:=false; ADOQuery.Connection := ADOConnection; ADOQuery.Close; ADOQuery.SQL.Clear; ADOQuery.SQL.Add('SELECT * From UserInfomation'); ADOQuery.Open; while not ADOQuery.Eof do begin MyString:=ADOQuery.FieldByName('UserName').AsString; if MyString=LoginName then Result:=true; ADOQuery.Next; end; finally ADOQuery.Free; CoUnInitialize; end; except Result := False; end; finally Unlock; end; end; function ReadUserPassW(PassW:string):Boolean; var ADOQuery: TADOQuery; MyString: string; begin Lock; try CoInitialize(nil); ADOQuery := TADOQuery.Create(nil); ForceConnectedToDatabase(true); try try Result:=false; ADOQuery.Connection := ADOConnection; ADOQuery.Close; ADOQuery.SQL.Clear; ADOQuery.SQL.Add('SELECT * From UserInfomation'); ADOQuery.Open; while not ADOQuery.Eof do begin MyString:=ADOQuery.FieldByName('Pass').AsString; if (MyString=PassW) then Result:=true; ADOQuery.Next; end; finally ADOQuery.Free; CoUnInitialize; end; except Result := False; end; finally Unlock; end; end; begin FirstReceiveString := AContext.Connection.IOHandler.ReadLn; if FirstReceiveString = '' then begin AContext.Connection.IOHandler.WriteLn('NO_USER_NAME'); AContext.Connection.Disconnect; Exit; end; i := pos(' ', FirstReceiveString); AUserName := Copy(FirstReceiveString, 1, i - 1); Delete(FirstReceiveString, 1, i); Password := FirstReceiveString; lst := FUsers.LockList; try FLockUI.Enter; try if ReadUserName(AUserName)=false then begin AContext.Connection.IOHandler.WriteLn('NotRegistered'); exit; end; if ReadUserPassW(Password)=false then begin AContext.Connection.IOHandler.WriteLn('WrongPassword'); exit; end; finally FLockUI.Leave; end; for i := 0 to lst.Count - 1 do begin if SameText(TUser(lst[I]).UserName, AUserName) then begin AContext.Connection.IOHandler.WriteLn('USER_ALREADY_LOGINED'); AContext.Connection.Disconnect; Exit; end; end; Client := TUser.Create(AContext.Binding.PeerIP, AUserName, AContext.Binding.PeerPort, AContext); lst.Add(Client); CCount := CCount + 1; CData.PlayerName[lst.Count - 1] := AUserName; Client.Lock; try Client.Context.Connection.IOHandler.WriteLn('LOGINED' + ' ' + IntToStr(lvUsers.Items.Count)); finally Client.Unlock; end; finally FUsers.UnlockList; end; SendMessage(FormHanlde, WM_REFRESH_USERS, Ord(rpAppendItem), integer(Client)); End;