PDA

Visualizza la versione completa : Winsock problema invio email c++


jtb
10-12-2008, 20:35
Salve a tutti sono un modestissimo programmatore c++ che ha iniziato da poco e ho un problema:

Tramite diverse guide sul web ho iniziato a sviluppare un programma che tramite le winsock si connette ad un server smtp di posta (in questo caso "smtp.net.vodafone.it") e permette di inviare email.

Leggendo e rileggendo diverse guide ho iniziato a capire le winsock fino ad arrivare a questo codice:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <iostream.h>
#include <winsock.h>
#include <string.h>
#include <mem.h>
#pragma hdrstop
char buff[256];
//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
SOCKET clientsocket;
SOCKADDR_IN addr;
hostent * hostentrata;
char messaggio[80];
short port;
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
int nLen=sizeof(SOCKADDR);
int ricv;
if (WSAStartup(wVersionRequested, &wsaData)!= NO_ERROR)
{
cout << "Errore di Inizializzazione" << endl;
goto fine;
}
port = 25;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("83.224.64.25");
addr.sin_port = htons(port);
clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(clientsocket, (LPSOCKADDR)&addr, sizeof(addr)) < 0)
{
printf("Errore nella connessione con il Server\n");
goto fine;
}
dinuov:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t";
cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
sendto(clientsocket,buff,sizeof(buff),0,(LPSOCKADD R)&addr, nLen);
goto dinuov;
fine:
system("pause");
}
//---------------------------------------------------------------------------

All'inizio era un po diverso ma mi dava lo stesso inspiegabile problema: Appena connesso al server smtp di vodafone ricevo il nome del server e i vari parametri verificati anche con telnet.
Come invio la stringa di autenticazione "helo nomemiocomputer" il server mi risponde con "pleased to meet you". Fin ora tutto normale ma quando invio un altro messaggio il server mi dice (500 5.5.1 Command unrecognized: ""). Da quanto mi è sembrato di capire il server riceve una stringa nulla. Potete aiutarmi!!!

oregon
10-12-2008, 20:41
Se non inserisci il codice tra i tag CODE non si capisce praticamente nulla ...

In ogni caso, quando dici "quando invio un altro messaggio" a quale parte del codice ti riferisci ?

jtb
10-12-2008, 23:36
Mi riferisco al ciclo dinuov:

dinuov:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t"; ------------>Qui ricevo il messaggio di avvenuta connessione senza problemi.

cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
sendto(clientsocket,buff,sizeof(buff),0,(LPSOCKADD R)&addr, nLen);
goto dinuov; ---------->Qui inserisco il messaggio "helo nomemiocomputer" e ritorno all'inizio del ciclo dinuov.

dinuov:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t"; ------------>Di nuovo a questo punto ricevo l'ok del server.

cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
sendto(clientsocket,buff,sizeof(buff),0,(LPSOCKADD R)&addr, nLen);
goto dinuov; ---------->Inserisco il secondo messaggio "mail from: <mioindirizzodiposta>" e
ritornando ancora una volta all' inizio del ciclo dinuov la risposta del sever è 500 5.5.1 Command unrecognized: "" che sicuramente significa che ha ricevuto una stringa nulla.
Mi spiace non essere chiaro ma ancora non conosco molto bene il linguaggio e sono sicuro che l'errore e una qualche stupidata che non riesco a trovare.....

oregon
11-12-2008, 07:38
Le parti in rosso sono aggiunte/correzioni da farsi ...



strcpy(buff,messaggio);
strcat(buff, "\n");
sendto(clientsocket,buff,strlen(buff),0,(LPSOCKADD R)&addr, nLen);

jtb
11-12-2008, 15:22
Grazie......finalmente ho risolto il problema ma ho un altra domanda:

Adesso riesco a comunicare col server, pero solo se seguo il ciclo richiesta-risposta-richiesta cioè se dopo aver richiesto un comando al server ricevo subito la risposta. Infatti dopo aver inserito il mittente ed il ricevente, quando inserisco "data" per scrivere il messaggio" e ricevo la risposta di iniziare a scrivere non posso inserire tutti i dati che voglio perché se premo invio il programma attende invano una risposta del server che non arriverà finché non avrò finito di scivere il messaggio utilizzando il metodo "a capo-punto-invio".

Il punto è: Posso mettere una specie di intervallo massimo di attesa per la funzione recvfrom in modo che se il server non risponde posso continuare l'esecuzione del programma e inviare altre stringhe???

oregon
11-12-2008, 15:46
No ...

Pero' il tuo codice dovrebbe sapere quando ha inviato il comando DATA e da quel momento, fino al . finale, dovrebbe "saltare" la recv ...

jtb
11-12-2008, 16:59
Ok ho risolto anche questo ma i problemi non vogliono finire......Ho modificato l'ultima parte del codice cosi:

dinuov:
if (val==1) { ------->Qui controlla la variabile val che mi dice quando ho usato "Data"
goto salto;
}
risult:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t";
salto:
cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
strcat(buff, "\n");
sendto(clientsocket,buff,strlen(buff)+1,0,(LPSOCKA DDR)&addr, nLen);
strcpy(buff,messaggio);
buffbuff=(char*)buff;
if (buffbuff=="Data"||buffbuff=="data") { --->Qui controllo se "Data" è stato inviato, se è
if (!val==1) { cosi e val non è già uguale ad 1, val vale 1 e
val=1; il programma viene rimandato a risult in modo
goto risult; che il programma non controlli la variabile val
} e ascolti la risposta al comando "data". Dopo
} la risposta posso inviare cosa voglio però se
if (buffbuff==".") { --->Questo controllo voglio lasciare una o più righe vuote tipo per
val=0; indica al programma segnalare al server che ho finito di scrivere il
} che val=0 e quindi programma si blocca e da quanto ho visto
goto dinuov; che può riprendere sembra attendere una risposta dal server.
la normale esecuzione.

E difficile essere più chiaro di cosi ma sembra che la funzione sendto non accetti stringhe vuote. Chiedo ancora una volta il tuo immenso aiuto!!!!!!!!!!!!!

jtb
11-12-2008, 17:11
Eeehm.....La pagina di risposta ha formattato male il precedente messaggio.....Eccolo qui.

Ok ho risolto anche questo ma i problemi non vogliono finire......Ho modificato l'ultima parte del codice cosi:

dinuov:
if (val==1) { ------->Qui controlla la variabile val che mi dice quando ho usato "Data"
goto salto;
}
risult:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t";
salto:
cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
strcat(buff, "\n");
sendto(clientsocket,buff,strlen(buff)+1,0,(LPSOCKA DDR)&addr, nLen);
strcpy(buff,messaggio);
buffbuff=(char*)buff;
if (buffbuff=="Data"||buffbuff=="data") { --->Qui controllo se "Data" è stato inviato, se è
if (!val==1) { \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\cosi e val non è già uguale ad 1, val vale 1 e
val=1; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\il programma viene rimandato a risult in modo
goto risult; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\che il programma non controlli la variabile val
} \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ e ascolti la risposta al comando "data". Dopo
} \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ la risposta posso inviare cosa voglio però se
if (buffbuff==".") { --->Questo controllo \\\\\\\voglio lasciare una o più righe vuote tipo per
val=0; \\\\\\\\\\\\\\\\\\\indica al programma \\\segnalare al server che ho finito di scrivere il
} \\\\\\\\\\\\\\\\\\\\\\\\\\che val=0 e quindi \\\\programma si blocca e da quanto ho visto
goto dinuov; \\\\\\\\\\\\\che può riprendere \\\\sembra attendere una risposta dal server.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\la normale esecuzione.

E difficile essere più chiaro di cosi ma sembra che la funzione sendto non accetti stringhe vuote. Chiedo ancora una volta il tuo immenso aiuto!!!!!!!!!!!!!

oregon
11-12-2008, 18:02
Scusa, ma se non usi i tag CODE e non scrivi il codice formattato, questo non puo' essere seguito (a parte che e' gia' difficile seguirlo dato che usi i goto ...).

E non capisco quasi nulla ... qual e' il problema?

jtb
11-12-2008, 18:16
In parole povere il codice che ti ho specificato unito con le tue correzioni funziona quando invio una stringa con almeno un carattere ma se per chiudere per esempio il messaggio, non posso inviare una stringa nulla perchè il programma si blocca...

Ecco il codice cambiato rispetto al primo che ti ho inviato:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <iostream.h>
#include <winsock.h>
#include <string.h>
#include <mem.h>
#pragma hdrstop
char buff[256];
AnsiString buffbuff;
int val=0;
//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
SOCKET clientsocket;
SOCKADDR_IN addr;
hostent * hostentrata;
char messaggio[80];
short port;
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
int nLen=sizeof(SOCKADDR);
int ricv;
if (WSAStartup(wVersionRequested, &wsaData)!= NO_ERROR)
{
cout << "Errore di Inizializzazione" << endl;
goto fine;
}
port = 25;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("83.224.64.25");
addr.sin_port = htons(port);
clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(clientsocket, (LPSOCKADDR)&addr, sizeof(addr)) < 0)
{
printf("Errore nella connessione con il Server\nPremi invio per uscire.");
goto fine;
}
dinuov:
if (val==1) {
goto salto;
}
risult:
memset(buff,0,sizeof(buff));
ricv=recvfrom(clientsocket,buff,sizeof(buff),0,(LP SOCKADDR)&addr, &nLen);
printf("%s\n",buff);
cout << "\t";
salto:
cin.get(messaggio, 256, '\n');
while (cin.get() != '\n');
strcpy(buff,messaggio);
strcat(buff, "\n");
sendto(clientsocket,buff,strlen(buff),0,(LPSOCKADD R)&addr, nLen);
strcpy(buff,messaggio);
buffbuff=(char*)buff;
if (buffbuff=="Data"||buffbuff=="data") {
if (!val==1) {
val=1;
goto risult;
}
}
if (buffbuff==".") {
val=0;
}
goto dinuov;
fine:
closesocket(clientsocket);
WSACleanup();
getchar();
}
//---------------------------------------------------------------------------

Prova a guardarlo cosi com'è tanto non è poi molto diverso dal primo che ti ho mandato comunque credo che SENDTO non accetti il buffer "Buff" se questo è Nullo. E comunque un ipotesi magari e solo un mio stupido errore nella correzione, rispetto al primo codice da me fornito.

Loading