Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jun : Re: TIDCmdTCPServer
| Subject: | Re: TIDCmdTCPServer |
| Posted by: | "Roberto Colpani" (roberto.colpa..@vetrariafratellicolpani.it) |
| Date: | Fri, 16 Jun 2006 08:14:57 |
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> ha scritto nel messaggio
news:449048ab$1@newsgroups.borland.com...
>
> "Roberto Colpani" <roberto.colpani@vetrariafratellicolpani.it> wrote in
> message news:449013aa$1@newsgroups.borland.com...
>
>> UserList := TObjectList.Create(True);
>
> Indy servers are multithreaded. You should be using a thread-safe
> container
> instead, such as TThreadList. Or at least use a separate TCriticalSection
> to protect the TObjectList.
>
>> if Assigned(ASender.Params) then
>
> That is not the correct way to check for parameters. TIdCommand always
> instantiates the Params property regardless of the ParseParams property.
> You should be checking the Count instead, ie:
>
> if ASender.Params.Count > 1 then
>
>> { Command: 'UnRegisterUser;UserName ComputerName'}
>> Index := 0;
>
> That variable is not being used for anything an should be removed.
>
>> if (AUser.UserName = ASender.Params[0]) and (AUser.ComputerName =
>> ASender.Params[1]) then
>> begin
>> UserList.Remove(AUser);
>> Break;
>> end;
>
> Since you already know the exact index of the User, you should use
> Delete()
> instead of Remove(). That way, the list doesn't have to be iterated
> through
> a second time:
>
> if (AUser.UserName = ASender.Params[0]) and (AUser.ComputerName =
> ASender.Params[1]) then
> begin
> UserList.Delete(Counter);
> Break;
> end;
>
>> procedure TMainForm.IdCmdTCPServer1CommandHandlers2Command(ASender:
>> TIdCommand);
>> begin
>> ASender.SendReply;
>> end;
>
> That is not needed at all. The Reply is automatically sent when the event
> handler exits, if it hasn't already been sent. Since you are not changing
> the Reply at all, you should get rid of that event handler completely, and
> let the TIdCommandHandler send its design-time values automatically.
>
>> procedure TMainForm.Showconnecteduser1Click(Sender: TObject);
>
> Here, you are accessing the UserList from the main thread. So you
> definately need to protect the list from multi-threaded access. If a user
> is registered or unregistered while the OnClick handler is still running,
> the list is being updated and will screw up the access.
>
> Now, with all of that said, there is nothing you have shown that can be
> causing one command handler to show another command handler's replies like
> you described earlier. Each command handler is completely separate for
> the
> other handlers. Without seeing everything the client is actually doing,
> my
> guess at this point would be that you sent a command without reading its
> reply, or maybe you didn't read the server's Greeting. Either way, by the
> time you sent the 'Prova' command, the server's previous reply was likely
> still in the socket's InputBuffer in front of the reply for the 'Prova'
> command.
>
>> I thought that with sendreply method I could do this thing
>
> You can. It sounds like you just aren't reading everything properly on
> the
> client side. The server side is fine, other than the points I mentioned
> above.
>
>
> Gambit
>
Thanks very much.
On client side on the onconnect method I have this code:
procedure TfrmMain.TangoClientConnected(Sender: TObject);
begin
TangoClient.SendCmd('RegisterUser;' + UserName + ' ' + ComputerName);
end;
Now I have modify the code like so:
procedure TfrmMain.TangoClientConnected(Sender: TObject);
begin
TangoClient.SendCmd('RegisterUser;' + UserName + ' ' + ComputerName);
TangoClient.GetResponse(200);
end;
where the number 200 is the NormalReply.Code.
It's correct to do so?
Now my goal is done but I have another doubt:
with the TServerSocket with the SendText method I could send to every
connected user some string;
with the TIdCmdTcpServer how can I do the same things?
Thanks.