Newsgroup: it.comp.lang.delphi
Titolo: ListenException

In quale occasione nelle indy 9 e D7 su XP pro utilizzando 
TCPServer.Execute si scatena la ListenException ?
Daniele

 TCPServer.Execute si scatena la ListenException ?
Un metodo per scoprirlo è leggere i sorgenti dei componenti Indy...
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
Sorry forse ho postato la domanda sbagliata. Anche se la tua risposta è 
azzeccata e solo che..... ecco mi sà che non ci piglio così tanto.
Provo a riformulare la domanda.
Ho assegnato delle procedure a OnException e a OnListenException per la 
TCPServer, dove ricevo i dati attraverso la Execute della stessa.
Ogni volta che ricevo un pacchetto dati invio una risposta al client 
tramite Athread.Connection.writeln e poi chiamo la disconnectsocket 
nello stesso evento Execute.
In condizioni normali questo codice funziona regolarmente. In casi che 
non riesco a replicare si scatena la ListenException.
Quali possono essere (immagino tra tanti) i motivi più frequenti in cui 
viene sollevata questa eccezione ?
Daniele

 tramite Athread.Connection.writeln e poi chiamo la disconnectsocket.
Dovresti chiudere con AThread.Connection.Disconnect, non ho mai visto usare 
la disconnectsocket.
Giorgio

Giorgio Padoan ha scritto:

In effetti inizialmente utilizzavo la Disconnect ma mi generava una 
eccezione ogni volta mentre con la disconnectsocket no.
Mi domandavo anche quale era il metodo ideale per ricevere i dati 
considerando che o un massimo di caratteri da ricevere (da 1 a 10 byte 
escluso terminatore). Oltre alla readln cosa mi consigliate ?
Daniele

 Mi domandavo anche quale era il metodo ideale per ricevere i dati 
E' ideale scrivere su socket la dimensione dei dati e poi i dati di
seguito.
Con i metodi WriteCardinal e WriteStream di TIdTCPClient e ReadCardinal e
ReadStream di TIdTCPServerConnection te la cavi (quest'ultimo è il tipo di
AThread.Connection).



Dovresti indagare su quell'eccezione del tutto anomala.
Prova a postare un po di codice.
Giorgio 

 
Dunque se non disconnetto il socket che succede ? bhè ecco la 
disconnetsocket è stata usata in quanto in alcuni esempi che ho trovato 
veniva usata e ho pensato fosse necessaria.
Nella OnException
procedure TForm1.IdTCPServer1Exception(AThread: TIdPeerThread;
   AException: Exception);
   var mis : string;
begin	
	//Scrive l'eccezione in un file:
     ADDLOG('IdTCPServer1Exception',AException.Message,'ND',True);
end;
Ecco cosa compare nel file ripetuto infinite volte e solo alla chiusura 
dell'applicazione:
12/08/2006 16:58:07;IdTCPServer1ListenException;Error on call Winsock2 
library function accept: Chiamata a WSAStartup non eseguita 
dall'applicazione oppure errore di WSAStartup;ND;***;
Il codice nella listenexception:
procedure TForm1.IdTCPServer1ListenException(AThread: TIdListenerThread;
   AException: Exception);
begin
//Scrive l'eccezione in un file:
   ADDLOG('IdTCPServer1ListenException',AException.Message,'ND',True);
end;
Nella Execute
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
Var
  Dati       : string;
  risp       : string;
begin
	try
     Dati := AThread.Connection.ReadLn(#13#10,1000);
     if (Trim(Dati) = '') then begin
     	//provato non si aggiunge mai nel log
       try
         AThread.Connection.DisconnectSocket;
         except
           ADDLOG('IdTCPServer1Execute - A','Errore su 
disconnessione','Dati:-Null-',True);
       end;
     	ADDLOG('IdTCPServer1Execute B','Dati:-Null-','(1)',False);
       Exit;
     end;
   	except
       try
         AThread.Connection.DisconnectSocket;
         except
           ADDLOG('IdTCPServer1Execute - 1A','Errore su 
disconnessione','Dati:-'+Trim(Dati)+'-',True);
       end;
    	 	ADDLOG('IdTCPServer1Execute - 1B','Err in ric. dati 
Dati:'+Trim(Dati)+'-','-',True);
     	Exit;
   end;
   try
   	if Trim(dati) <> '' then begin
         risp := 'OK';
         end
         else begin
           risp := 'NOK';
       end;
       try
         AThread.Connection.WriteLn(risp);
         AThread.Connection.DisconnectSocket;
         if risp = 'NOK' then Exit;
         except
         	//ANCHE QUI TUTTO BENE
          ADDLOG('IdTCPServer1Execute - 2','AThread.Connection.WriteLn 
su dati:-'+Trim(Dati)+'-',' Risposta: '+ risp,True);
       end;
     end;
     except
       try
         AThread.Connection.DisconnectSocket;
         except
           ADDLOG('IdTCPServer1Execute - 3A','Errore su disconnessione 
del socket','Dati:-'+risp+'-',True);
       end;
ADDLOG('IdTCPServer1Execute - 3B','Errore in lettura dati da','Risposta: 
'+risp+' Dati: '+Trim(Dati),True);
       Exit;
   end;
end;
Ho triggerato il triggerabile penso... in ogni caso questa eccezione si 
verifica senza ripetitività per un motivo che non conosco.
Grazie dell'aiuto.
Daniele

 veniva usata e ho pensato fosse necessaria.
Non devi disconnettere il socket, come già detto.


 
Ho triggerato la OnException e se non disconnetto il socket dopo la 
chiamata ad una write mi restituisce un errore sulla TCPServer1.OnException
*** TCPServerException *** Connection Closed Gracefully.
ecco perchè devo disconnettere dopo la ricezione e l'invio della 
risposta al client.
Daniele

 risposta al client.
Non č questo il modo corretto di lavorare.  Il socket non va disconnesso
tutte le volte.


 
Ok allora consigli per l'uso (io non ci capisco piů..) ? Tipo un esempio 
funzionante e formalmente perfetto di comunicazione client/server usando 
il tcpserver.
Daniele

 ha scritto nel messaggio 
news:44e075a8$0$30239$4faf...@reader1.news.tin.it...

Dipende da cosa richiede il client, se i comandi sono molteplici non ha 
senso disconnettersi e riconnettersi ad ogni comando eseguito.
Se invece la richiesta si puo' esaudire in un comando una tantum allora va' 
bene chiudere a fine comando.
Giorgio 

 
Io dal client invio un solo dato che il server valuta e invia una sola 
risposta al client sempre e in ogni caso, e poi si disconnette.
Questa architettura però, una volta ogni tanto (anche a distanza di ore 
e dopo aver resettato la macchina) fa saltar fuori l'eccezione di cui 
dicevo.
Una curiosità: lavorando sotto XP Pro la proprietà del tcp server 
ReuseSocket come deve essere impostata ? (rsFalse,rsOSDependent,rsFalse)
Insomma così non è affidabile e non riesco a trovare l'errore.

 Insomma così non è affidabile e non riesco a trovare l'errore.
Usa rsOSDipendent, che fa tutto in automatico.
Non ho ancora compreso cosa succede se interrompi la connessione con 
Connection.Disconnect, come andrebbe fatto.
Hia pensato a fare un upgrade dell'Indy?
Giorgio 

 
Ok per rsOSDipendent, no perchè in rete si dice che in delphi 7 sia 
preferibile usare le 9 alle 10. Ne sai qualcosa ?
Daniele

 bene chiudere a fine comando.
Neanche.


 
A quanto pare potrebbe essere un errore programmatico di come viene 
effettuato l'invio dei dati dal client quindi. Provo a riguardare gli 
esempi indy relativi alla versione che uso.
Daniele

 Daniele
Guardando gli esempi Indy (Basic Client/Server, Ping, 
SendReceiveRecords..) ho notato in particolare che un possibile errore 
lo commetto lato client. Ciò non toglie che è sempre possibile 
disconnettere il server e anche direi ovviamente. Mi stà bene che la 
tecnica non sia perfetta in quanto, un server per logica dovrebbe essere 
sempre pronto a 'servire' e se mai è il client a disconnettersi (e 
questo deve avvenire).
Ok mi guarderò meglio il client.
Per ora ringrazio tutti.
Daniele

(e questo deve avvenire).
Non necessariamente.  Se il colloquio con il server č frequente, il client
deve rimanere connesso.


 preferibile usare le 9 alle 10. Ne sai qualcosa ?
Non so a chi ti riferisca di preciso con "in rete si dice", ma credo che
la scelta sia motivata dal fatto che nella suite versione 10 sono stati
fatti dei cambiamenti rispetto alle versioni precedenti.  Cambiamenti che
probabilmente impattano sulle versioni esistenti del codice che utilizza
gli Indy.


 
Bene pare risolto questo nodo Gordiano. A questo è sicuramente il client 
ad avere un pò di problemi. Gli darò un'altra occhiata (non è in delphi 
ma in c# sotto .NET 1.1 ecco perchè non ne parlo qui). Grazie...

 Un server non va "disconnesso".
Si disconnette ad esempio IIS per inattivita' di un client dopo un certo 
time-out.
Diciamo che e' preferibile sia il Client a disconnettersi.
Giorgio

 
Giusto per essere sicuro di intraprendere la strada giusta, il client 
può disconnettersi dal server ogni volta che termina la sua 
comunicazione e in quel caso deve effettuare altre operazioni (buffer, 
connessione disallocazione risorse etc) oppure è sufficiente un semplice 
disconnect ?
Daniele

 Diciamo che e' preferibile sia il Client a disconnettersi.
Non ci siamo capiti: il web server disconnette la connessione verso il
*client* (se non c'è un keep alive), ma parlare di "disconnessione del
server" è una cosa diversa.  Il time-out sulle connessioni dei client è
attivo e regolabile per molte applicazioni server, tra cui quasi tutti i
DB.
In sostanza, è *sempre* il client a disconnettersi, ma o si disconnette o
subisce la disconnessione.


 comunicazione 
Basta invocare la Disconnect, ma comunque stai bene attento a non eseguire
connessioni e disconnessioni con troppa frequenza.  Sinceramente non
capisco la tua necessità di chiudere per forza la connessione del client...


 subisce la disconnessione.
Certo dire che un Server si diconnette va sempre inteso che chiude il socket 
abbinato al Client ma non quello principale che rimane in Listen finche' il 
"servizio" e' attivo.
Giorgio

 Certo dire che un Server si diconnette[...]
Diciao che un server non si disconnette, disconnette la connessione del
client.  La "disconnessione", in generale, implica un troncamento della
comunicazione, quindi è bene intendere *quale* comunicazione particolare
viene interrotta.


 
Ok, disconnettere il client mi si rende necessario in previsione di una 
ottimizzazione del consumo energetico di dispositivi mobili. La 
disconnessione mi permette quindi di interrompere la connessione 
wireless del portatile e risparmiare batteria. Diciamo che voglia 
disconnettere dopo 2 minuti dall'ultima comunicazione, posso farlo 
attraverso il timeout del client ?
Daniele