Newsgroup: it.comp.lang.c++
Titolo: Telnet?

> 
http://www.geocities.com/sunsetstrip/stage/7787
 <<
<<<<<<<<<<<< _
Metal...@iol.it
 >>>>>>>>>>>>>>
(remove asterisk to reply)

Potresti spiegare meglio cos'e' che non funziona?
Per fare un programma tipo telnet e' sufficiente utilizzare la classe
CSocket di MFC in modalita' sincrona e ricevere e inviare linee terminate da
0Dh e 0Ah. Se non ti piace la classe CSocket puoi sempre usare direttamente
le funzioni delle socket.
Antonio Donatiello.

...

In effetti sto usando un oggetto derivato dalla CSocket (almeno avevo preso
la strada giusta ;-))
Quello che succede è questo: io inserisco l'indirizzo e porta del server e
faccio la CSocket.Connect().
Se questa va a buon fine (se ritorna TRUE) allora la connessione è
stabilita. Il programma si mette in ascolto e manda i dati nel caso che
l'utente digiti qualche cosa.
Il metodo per gestire la ricezione dei dati è questo:
void CMySocket::OnReceive(int nErrorCode)
{
 char pBuf[256];
 char *p;
 UINT nReceived;
 nReceived=Receive(pBuf,sizeof(pBuf-1));
 pBuf[nReceived]='\0';//NULLtermina il buffer
 //invia il contenuto del pBuf alla finestra m_hDestination
 p=pBuf;
 while (*p){
  ::PostMessage(m_hDestination,WM_CHAR,(WPARAM)*p,DATA_RECEIVED);
  p++;
 };
}
m_hDestination è una var membro di CMySocket di tipo HWND che contiene
l'handle della finestra che visualizza i dati ricevuti.
Stavo pensando: magari il motivo per cui non mi funziona è perchè il
protocollo telnet vuole che all'inizio della connessione i due programmi si
scambino qualche stringa standard per riconoscere il protocollo.... è vero
questo? (non mi sono ancora documentato)


Se usi la CSocket in modalita' asincrona non hai bisogno di utilizzare
l'evento OnReceive() ma basta che chiami Receive() quando vuoi ricevere e
Send() quando vuoi spedire.
Telnet non dovrebbe avere un protocollo particolare. Sicuramente devi prima
fare tu una Receive() per ricevere l'hello dell'HOST e poi alternativamente
gli dai il comando con Send() e ricevi la risposa con Receive(). Non so come
sono gestite le risposte multilinea. Nei protocolli POP3 e SMTP che conosco
meglio le risposte multilinea sono terminate con una riga contenete solo il
punto (".").
Ciao.
Antonio Donatiello.

Per errore ho scritto modalita' asincrona ma volevo dire sincrona!
Antonio Donatiello.


mi potresti spiegare in due parole che differenza c'è tra una socket
sincrona e una asincrona?
Da quello che ho capito dall'help on-line del VC++, abbiamo la CAsyncSocket
e la CSocket (derivata dalla prima).
Quest'ultima dovrebbe implementare la socket sincrona, dunque se io derivo
una mia classe CMySocket dalla CSocket, anche la mia nuova classe
implementerà una socket sincrona, giusto?
Ma forse sbaglio ad usare la receive.
Prima di inserire il codice nella OnReceive il mio programma creava un
thread al momento della connessione (con la CSocket.Connect) che si occupava
di loopare all'infinito e ogni volta eseguire la CSocket.Receive().
Questo però non funzionava perchè quando sulla socket non c'erano più dati
da leggere il programma terminava con un errore di protezione generale.
Dunque è giusto chiamare una sola volta la CSocket.Receive() all'interno del
metodo CMySocket.OnReceive()?


Le socket in modalita' sincrona interrompono il programma quando effettui
una Receive(), Send(), Connect() fino a quando la funzione non e' terminata.
Le socket in modalita' asincrona invece tornano il controllo e ti chiamano
gli eventi associati alle funzioni quando queste sono completate.
Ad esempio se chiami Connect() in modalita' asincrona ti verra' chiamata la
OnConnect() per notificarti quando la connect e' riuscita (o e' fallita).
La OnReceive() invece ti viene chiamata quando ci sono dati da leggere ed
all'interno chiami la Receive() per leggere i dati.
La OnSend() dovrebbe essere chiamata quando "puoi" inviare i dati ed
all'interno chiami la Send(). (Ho avuto dei problemi in tal senso).
Se derivi da CAsyncSocket usi la modalita' asincrona, se derivi da CSocket
usi quella sincrona (a meno di impostazioni particolari).
Io quando ho usato la CSocket non ho implementato la OnReceive() (anche se
l'help dice che si puo' fare) ma chiamavo direttamente Receive().
Chiaramente se non c'e' nulla da leggere il programma rimane in attesa (mi
sembra che vada in time-out dopo un certo tempo), ma non mi andava in crash.
Per evitare di restare bloccati in una Receive() occorre seguire
strettamente il protocollo e quindi ricevere solo quando e' giusto che
dall'altra parte qualcuno ti spedisce qualcosa.
Io ho cominciato usando la classe CAsyncSocket perche' mi serviva che il
programma girasse in "multitasking" su Windows 3.11 ma da quando sviluppo
per Win95 ho usato CSocket in modalita' sincrona.
Ciao.
Antonio Donatiello.