winsock и smtp/pop3
Вот немного более подробное изложение данной ситуации: http://forum.codenet.ru/showthread.php?s=&threadid=22600
Кто нибудь имеет опыт в написании почтового клиента используя только winsock2? Не получается нормально начать сессию с smtp/pop3 серверами - удачный коннект, а далее или принудительный разрыв связи со стороны сервера, или тишина опять таки со стороны сервера. При этом клиент работает нормально по http с тем же сервером. Протоколы smtp и pop3 знаю достаточно неплохо и поэтому не могу понять, что нужно серверу? По идее он должен первым начать передачу после установления транспортного соединения...
Вот немного более подробное изложение данной ситуации: http://forum.codenet.ru/showthread.php?s=&threadid=22600
А что тут у тебя не получается?
Возьмем к примеру протокол smtp и попытаемся передать какое нить почтовое сообщение содержащее только текст на некий электронный адрес,код на С++ мог бы выглядить следующим образом придерживаясь указаний RFC 821: (CClientSocket,CSocket собственые классы здесь не показаны - инкапсулируют функции winsock2)
int GetErrorSmtpCode(LPVOID data,DWORD size)
{
if(size<3 || data==0) return -1;
char retval[4];
strncpy((char*)retval,(char*)data,3);
return atoi(retval);
}
int SendMail(char* SMTP_SERVER,char* HOST_FROM,char* HOST_TO,char* MSG_FROM,char* MSG_TO,char* MSG)
{
CClientSocket cs;
cs.Create();
SOCKADDR_IN adr_smtp_port;
ZeroMemory(&adr_smtp_port,sizeof(SOCKADDR_IN));
hostent* hostmail=gethostbyname(SMTP_SERVER);
if(hostmail==0) return 0;
adr_smtp_port.sin_family = AF_INET;
adr_smtp_port.sin_addr.S_un.S_addr=*(DWORD*)(hostmail->h_addr_list[0]);
adr_smtp_port.sin_port=ntohs(25);
if(cs.Connect((PSOCKADDR)&adr_smtp_port,sizeof(adr_smtp_port))==1)
{
DWORD bufsize=4096;
LPVOID chBuf=malloc(bufsize);
int errval=0;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval==220)
{
//strcpy((char*)chBuf,"HELP");
//cs.WriteData(chBuf,strlen((char*)chBuf));
char hostname[50];
gethostname((char*)hostname,50);
sprintf((char*)chBuf,"HELO %s\r\n",hostname);
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=250) return 0;
sprintf((char*)chBuf,"MAIL FROM:<%s>\r\n",(char*)HOST_FROM);
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=250) return 0;
sprintf((char*)chBuf,"RCPT TO:<%s>\r\n",(char*)HOST_TO);
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=250) return 0;
sprintf((char*)chBuf,"DATA \r\n");
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=354) return 0;
char chBuf2[5000];
strcpy((char*)chBuf,"Date: 26 Аug 76 1429 EDT\r\n");
sprintf((char*)chBuf2,"From: %s\r\n",MSG_FROM);
strcat((char*)chBuf,(char*)chBuf2);
sprintf((char*)chBuf2,"Subject: %s\r\n",NUMBER);
strcat((char*)chBuf,(char*)chBuf2);
sprintf((char*)chBuf2,"cc: %s\r\n",MSG_TO);
strcat((char*)chBuf,(char*)chBuf2);
strcat((char*)chBuf,"MIME-Version: 1.0\r\n");
strcat((char*)chBuf,"Content-Type: text/plain; charset=windows1251\r\n");
strcat((char*)chBuf,"Content-Transfer-Encoding: 7bit\r\n");
char OutMsg[4096];
int out_len=4096;
strcpy(OutMsg,MSG);
strcat((char*)chBuf,(char*)OutMsg);
strcat((char*)chBuf,"\r\n.\r\n");
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=250) return 0;
sprintf((char*)chBuf,"quit \r\n");
cs.WriteData(chBuf,strlen((char*)chBuf));
bufsize=4096;
cs.ReadData(chBuf,&bufsize);
((DWORD*)chBuf)[bufsize]=0;
errval=GetErrorSmtpCode(chBuf,3);
if(errval!=221) return 0;
}
}
cs.DisconnectFromServer();
cs.Destroy();
return 1;
}
А что тут у тебя не получается?
Спасибо за поддержку конечно, но у меня уже давненько все получается ;)
См. ссылку, указанную в первом посте.