PDA

View Full Version : [C] Problema con recv()


Manugal
14-02-2010, 17:05
Ciao a tutti!

Sto sviluppando un mail server. Facendo la recv() su un socket, questa si comporta in modo strano. Questo è il codice della funzione (eseguita in un thread separato):


void SMTPCommands(THRD_PARAMS *tArgs)
{
....
int iResult;
SMTPSession *session=(SMTPSession *)malloc(sizeof(SMTPSession));
memset(session->request,0,sizeof(session->request));
while (!flagsGuard.ShutDown){
printf("Waiting for SMTP request...\n");
iResult=recv(tArgs->SMTPSocket,session->request,MAX_REQ_SIZE,0); // MAX_REQ_SIZE = 512
....


Succede che quando vado a interrogare il server tramite Telnet (RAW) sulla porta 25 di SMTP, inviando ad esempio il comando HELO, su session->request non mi ritrovo HELO\r\n (come mi aspetto), ma solo HELO e se faccio un'altra chiamata a recv() subito dopo questa allora mi legge il CRLF. Non capisco perché non lo legge tutto con un'unica recv().

cionci
14-02-2010, 17:53
iResult cosa contiene dopo ?

Manugal
14-02-2010, 18:05
iResult ritorna 4 (cioè i caratteri di HELO). E alla successiva chiamata a recv iResult vale 2 (ossia \r\n).

Le prove le sto facendo con PuTTy.

Manugal
14-02-2010, 18:10
Un'altra cosa strana sempre relativa a questo comportamento è che quando vado ad analizzare il codice con gdb, metto un breakpoint sulla riga della recv(). A quel punto se prima di digitare step su gdb immetto il comando da telnet e solo dopo digito step su gdb, allora in quel caso la recv() torna correttamente HELO\r\n. :confused:

cionci
15-02-2010, 01:38
Prima di tutto ti consiglio di fare una recv non bloccante.
Non hai garanzia che la RECV ti torni tutti i dati disponibili. Sapendo che nel tuo protocollo un comando deve finire con /r/n, se non trovi questi dati in fondo al comando allora continua a leggere.

Manugal
15-02-2010, 12:14
Grazie mille. Questa è una soluzione più elegante rispetto a quella che avevo trovato prima e cioè fare 2 recv una di seguito all'altra.