Newsgroup: it.comp.lang.delphi
Titolo: Socket in Delphi 2006

Ciao,
    sto portando la mia applicazione da Delphi7 a Delphi 2006. 
L'applicazione utilizza comunicazioni tramite socket utilizzando gli oggetti 
TIdTCPClient e TIdTCPServer (poi diventato TIdCmdTCPServer in Delphi2006).
    Per testare il programma è stata creata quindi una piccola applicazione 
che effettua ciclicamente richieste al server. In Delphi7 tutto liscio, ma 
quando ho portato l'applicazione (sia client che server) in Delphi2006, 
alcune volte il client da l'errore: "Already Connected". Dove sbaglio?
procedure prova;
var
    client: TIdTCPClient;
    i: Integer;
    cmd: Integer;
    params: String;
begin
    client:=TIdTCPClient.Create(self);
    client.Host:='10.0.0.222';
    client.Port:=59457;
    Randomize;
    for i:=1 to 100 do begin
        cmd:=Random(10);                        // Sceglie a caso un comando 
da eseguire
                                                             // tra i 10 
disponibili
        ...
        // Costruisce la stringa di richiesta del comando params
        ...
        cli.ConnectTimeout:=5000;
        cli.Connect;                                    // <-- A volte 
lancia l'eccezione: EIdAlreadyConnected
        cli.SendCmd('CMD '+IntToStr(cmd)+' '+params);
        cli.Disconnect;
    end;
    client.Free;
end; 

         cli.Disconnect;
Innanzitutto cambia con:
cli.Connect;
try
  cli.SendCmd(...);
finally
  cli.Disconnect;
end;
e poi dopo la Disconnect() dovresti comunque testare che il socket sia
effettivamente disconnesso, usando gli eventi del componente.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Ho apportato le modifiche che hai suggerito ma ho notato che il Socket 
continua ad essere connesso anche dopo il segnale di Disconnect (ho testato 
il valore della proprietą TIdTCPClient.Connected), ma non si riesce a 
chiuderla neanche con TIdTCPClient.Socket.Close come consigliato nella guida 
in linea. 

 continua ad essere connesso anche dopo il segnale di Disconnect
Devi attendere finché sia disconnesso, affidandoti all'evento di
TIdTCPClient, come già ti ho detto.


    Ok! Grazie dell'aiuto. Ora la connessione funziona, però è sorto un 
altro problema: l'oggetto TIdCmdTcpServer in Delphi2006 non invia (o sembra 
non inviare) il messaggio di testo contenuto nella proprietà Greeting.
    In Delphi7 il testo contenuto nella proprietà Greeting veniva inviato in 
automatico sul socket e poteva essere letto dal client connesso secondo 
questo filo logico:
Client                             Server
                                      Avvio il Server
Richiesta Connessione
Resto in attesa del
messaggio di benvenuto
                                      Connessione Accettata
Leggo il messaggio di
benvenuto
Proseguo con l'applicazione
    Ora invece il client rimane in loop sull'attesa del messaggio di 
benvenuto del server (una semplice stringa "OK").
    Qualcuno ha idea di come potrei risolvere il problema? 

 Qualcuno ha idea di come potrei risolvere il problema?
Innanzitutto ti sconsiglio di far comunicare client/server tramite
stringhe.
Adotta un sistema ed utilizza sempre quello.  Io preferisco mandare dati
"raw" per ogni tipo di comunicazione tra i due peer.
In generale, se adotti la tecnica di mandare uno stream dati tra client e
server, entrambi possono mettersi in attesa di un Integer che rappresenti
la grandezza dei dati e poi leggere il buffer che lo segue.
In questo modo, la comunicazione funziona senz'altro.


    A quanto dici il sistema non è molto ortodosso, ma ha sempre funzionato 
(l'applicazione prima girava in Delphi7 ed ora sto facendo il porting in 
Delphi2006) ed è molto utile in quanto mi permette di indicare se la 
connessione è andata a buon fine o di stampare a video immediatamente (sul 
client - terminale stupido) una descrizione dell'errore riscontrato. 
Tuttavia potrei restare ore in attesa per qualsiasi tipo di dati sul client, 
perché il problema è proprio il Server (componente TIdCmdTcpServer) che non 
invia risposte al segnale di connessione.
    Sicuramente sarà un problema che ho introdotto io, non conoscendo bene 
questa nuova versione di Indy10 (prima i cmd erano inclusi nel TIdTcpServer) 
perciò mi chiedevo se qualcuno ha già utilizzato un modello simile al mio e 
se può darmi qualche dritta in modo da evitare di dover rivedere 
completamente la comunicazione client-server.
    Grazie dell'aiuto,
    Antonio 

 invia risposte al segnale di connessione.
Un peer, in una comunicazione basata su socket, legge dati se i dati ci
sono, quindi il client riceve i dati se il server li scrive. 
Evidentemente il server non li scrive.  Se il client è in attesa di dati e
il server scrive dati, allora il client DEVE ricevere dati.  E'
impossibile che si sfugga a questo meccanismo.


 impossibile che si sfugga a questo meccanismo.
Infatti! E' proprio quello che dico io: il server non invia nulla. A questo 
punto mi chiedo se sto usando bene il messaggio di Greeting: basta 
semplicemente inserire la stringa da restituire al client a design-time e 
verrà inviato tutto in automatico all'occorrenza (come facevo in Delphi7) 
dal TIdCmdTcpServer o devo eseguire qualche altro comando (magari 
nell'evento OnConnect) per avere l'invio della stringa al momento della 
connessione?
    Saluti,
    Antonio 

 connessione?
Mai usata la stringa di Greeting.


 Mai usata la stringa di Greeting.
Ok,
    grazie comunque per i consigli.
    Antonio