Code:

#include "winsock.h" #include "conio.h" WSADATA ws; SOCKET s; struct sockaddr_in addr; hostent *d_addr; char text[1024]; int main() { if (FAILED(WSAStartup(MAKEWORD(1, 1), &ws))) { printf("Error in WSAStartup(...)n"); return 1; } if (INVALID_SOCKET == (s = socket(AF_INET, SOCK_STREAM, 0))) { printf("Error in socket(...)n"); return 1; } d_addr = gethostbyname("smtp.yandex.ru"); if (d_addr == NULL) { printf("Error in gethostbyname(...)n"); return 1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = *((unsigned *****) d_addr->h_addr); addr.sin_port = htons(25); if (SOCKET_ERROR == (connect(s, (sockaddr *) & addr, sizeof(addr)))) { printf("Error in connect(...)n"); return 1; } recv(s, text, sizeof(text), 0); printf("recv - %s", text); printf("%s", "h_name"); printf("Press any keyn"); getch(); } 

I'm just starting to learn with ++, I want to write a program that will connect to email. mail directly, while stopped on the connection, I can not enter the parameter with IP.

When compiling writes

In function 'int main()': 43: warning: assignment to 'u_long' from 'unsigned int ****' lacks a cast

I understand that the unsigned interval does not have enough memory? I would be grateful if someone could explain in detail the line

 addr.sin_addr.s_addr = *((unsigned **** *) d_addr->h_addr); 

If you remove it, a message is displayed when working in the console.

recv - 421 Cannot connect to SMTP server 0.0.0.0 <0.0.0.0:25>, connect error 100 49

I want to display the data obtained through

 d_addr = gethostbyname ("smtp.yandex.ru") 

But h_name is issued, i.e. just a string.

  • one
    Bring everything to a normal form! Impossible to read! - Alexey Lobanov

4 answers 4

And what data you want to withdraw?
To connect, you need to have a complete sockaddr_in structure, and in this structure, among other things, the destination address must be present .sin_addr.s_addr, network byte address and not an IP address or a mail address for example !!! gethostbyname function allows you to get information about the host by its DNS name, it returns a pointer to the hostent, the hostent has the address matrix h_addr_list, it has a char type, so that would fill sin_addr with one type ((unsigned long ) & addr.sin_addr) and the first value [0] (it is s_addr) fill in the first value from the address matrix ((unsigned long *) smtpServer-> h_addr_list) [0] [0], read about the pointers and you will understand why this looks like

 //Объявляем указатель на addr.sin_addr IN_ADDR* inSinAdrPtr = &addr.sin_addr; //Преабразовываем IN_ADDR в unsigned long //Теперь можно обратится к первому элементу //как в обычном массиве SinAdrArrayPtr[ x ] unsigned long * SinAdrArrayPtr = (unsigned long *)inSinAdrPtr; //Преабразовываем h_addr_list из char** в unsigned long** unsigned long ** AdrListMatrixPtr = (unsigned long **)smtpServer->h_addr_list; //и тут уже совсем все стало просто! SinAdrArrayPtr[0] = AdrListMatrixPtr[0][0]; 

Well, or you can write all this in one line =)

 ((unsigned long *)&addr.sin_addr)[0] = ((unsigned long **)smtpServer->h_addr_list)[0][0]; 

It seems something like this, but maybe something is wrong said, read msdn.

From doing nothing written a small primerchik, far from the best, but more or less working =)

 #include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "Ws2_32.lib") bool SendSMTPCommand(SOCKET sock, const char* data, char* recvBuffer, int bufferSize); void base64_encode(char *out, const char *data, unsigned int len); const char messageFormat[] = "from: %s\r\n" "to: %s\r\n" "subject: %s\r\n\r\n" "%s\r\n."; int main( int argc, const char* argv[] ) { if (argc != 7) { printf( "Please launch with parametrs:\n " "[file name] [Server] [Login] [Password] [Recipient] [Subject] [Message]\n" "For example : \nClientSMTP.exe smtp.yandex.ru MyMailBox@yandex.ru 12345 FriendMailBox@mail.ru \"Hi, how are you ?\" \"Please, talk to me!=)\"\r\n"); return 1; } //для удобства объявим по указателю на каждый параметр const char* server = argv[1]; const char* login = argv[2]; const char* pass = argv[3]; const char* rcpt = argv[4]; const char* subject = argv[5]; const char* message = argv[6]; //Инициализируем библиотеку, ОБЯЗАТЕЛЬНО!!! (см. msdn) WSADATA w; int error = WSAStartup (0x0202, &w); if (error != 0) { printf("Error load WinSock library.\nError code #%d\n", error); return 1; } if (w.wVersion != 0x0202) { printf("Error WinSock library version.\n"); WSACleanup (); return 0; } SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_port = htons( 25 ); //Порт по умолчанию для SMTP сервера HOSTENT* smtpServer = gethostbyname(server); if (!smtpServer) { printf("SMTP server is not available.\n"); WSACleanup (); return 0; } //unsigned означает что тип беззнаковый, //у вас же вообще тип не указан, по этому и ошибка! ((unsigned long *)&addr.sin_addr)[0] = ((unsigned long **)smtpServer->h_addr_list)[0][0]; //создаем сокет SOCKET sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sSocket == INVALID_SOCKET) { printf("Create socket failed with error: %d\n", WSAGetLastError()); WSACleanup (); return 0; } //подключаемся error = connect(sSocket, (LPSOCKADDR)&addr, sizeof(addr)); if (error == SOCKET_ERROR) { printf("Connect failed with error: %d\n", WSAGetLastError() ); closesocket(sSocket); WSACleanup(); return 1; } const int bufSize = 1024; char buffer[bufSize + 1]; //после подключения сервер нам представляется //так что нужно обязательно его послушать! error = recv (sSocket, buffer, bufSize, 0); if (error <= 0) { printf("Receives error: %d\n", WSAGetLastError()); closesocket(sSocket); WSACleanup(); return 1; } buffer[error] = 0; //не забываем про завершающий строку ноль printf("Recv: %s", buffer); //вот дальше я не уверен, нужно ли после EHLO домен приписывать //с синтаксисом SMTP команд не особо знаком //но в нагугленных примерах везде дописывали, и я дописал=) //отдельный указатель на login по тому что будем менять адрес const char* domain = login; do { //проверяем не равен ли первый символ собаке //и потом сдвигаем начало на следующий символ if (*domain++ == '@') //если равен @ выходим, domain содержит то что нужно! break; } while (*domain); //проверяем пока не дошли до конца строки sprintf(buffer, "EHLO %s", domain); //отправляем EHLO yandex.ru if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //отправляем AUTH LOGIN if (!SendSMTPCommand(sSocket, "AUTH LOGIN", buffer, bufSize)) return 1; //если код ответа 334 значит //сервер поддерживает AUTH LOGIN //и хочет что бы мы послали ему логин //334 VXNlcm5hbWU6 buffer[3] = 0; if (atoi(buffer) != 334) { send(sSocket, "QUIT", 4, 0); closesocket(sSocket); WSACleanup (); return 1; } //кодируем и отправляем логин base64_encode(buffer, login, strlen(login)); if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //кодируем и отправляем пароль base64_encode(buffer, pass, strlen(pass)); if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //проверяем успешно ли авторизовались buffer[3] = 0; if (atoi(buffer) != 235) { send(sSocket, "QUIT", 4, 0); closesocket(sSocket); WSACleanup (); return 1; } //указываем от кого sprintf(buffer, "MAIL FROM: %s", login); if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //указываем кому sprintf(buffer, "RCPT TO: %s", rcpt); if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //и добавляем само сообщение (с параметрами) if (!SendSMTPCommand(sSocket, "DATA", buffer, bufSize)) return 1; sprintf(buffer, messageFormat, login, rcpt, subject, message); if (!SendSMTPCommand(sSocket, buffer, buffer, bufSize)) return 1; //Прощаемся! send(sSocket, "QUIT", 4, 0); closesocket(sSocket); WSACleanup (); return 0; } bool SendSMTPCommand(SOCKET sock, const char* data, char* recvBuffer, int bufferSize) { printf("Send: %s\r\n", data); int err = send(sock, data, (int)strlen(data), 0); if (err == SOCKET_ERROR) { printf("Send failed with error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return false; } send(sock, "\r\n", 2, 0); *recvBuffer = 0; err = recv (sock, recvBuffer, bufferSize, 0); if (err > 0) { recvBuffer[err] = 0; printf("Recv: %s\n", recvBuffer); return true; } printf("Receives error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return false; } //Функция из интернета, кто автор к сожелению не помню. void base64_encode(char *out, const char *data, unsigned int len) { char *base64_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned char index2,index3; unsigned int i = 0; for(; i<len; (i+=3,data+=3,out+=4)) { *out = base64_set[*data >> 2]; index2 = (*data << 4) & 0x30; if(i+1<len) { index2 |= *(data+1) >> 4; index3 = ((*(data+1) << 4) & 0xFF) >> 2; if(i+2<len) { index3 |= *(data+2) >> 6; *(out + 3) = base64_set[*(data+2) & 0x3F]; } else { *(out + 3) = '='; } *(out + 2) = base64_set[index3]; } else { *(out + 2) = '='; *(out + 3) = '='; } *(out + 1) = base64_set[index2]; } *out = 0; } 

source + exe'shnik

  • 2
    Nichrome yourself you have a batch here. - Costantino Rupert
  • 2
    The very scary, horror: \ - lirik90
  • @ lirik90, and the server responses are not necessary to analyze? Your program code is generally only for a specific server, which requires AUTH and takes AUTH LOGIN. I am already silent that in a very busy network your program will simply fail, because at the beginning of the buffer received by recv (), you can easily get not the response code for this send (), but the rest of the response for the previous send (). Successful debag. - avp
  • @avp, I am very glad that you understand all the badness of this code, then the line of text right before the code is definitely not for you! ;) ps but still there is even a whole check that the server supports "AUTH LOGIN")) - lirik90
  • @ lirik90, I really didn’t look at the code (already 2 times), but it still seems to me that the sequence is sprintf (buffer, "EHLO% s", domain); // send EHLO yandex.ru if (! SendSMTPCommand (sSocket, buffer, buffer, bufSize)) return 1; // send AUTH LOGIN if (! SendSMTPCommand (sSocket, "AUTH LOGIN", buffer, bufSize)) return 1; either always send "AUTH LOGIN", or interrupt the work ( return 1; ). Not this way? - avp

To fill the server address, I use this function

 // avp #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32 // gcc ... -lws2_32 -lwsock32 #include <winsock2.h> #include <ws2tcpip.h> #include <windows.h> #else #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #endif /* make ip-addr & port in allocated struct sockaddr returns 0 - OK, 1 - unknown host, 2 - bad port (service) */ int make_tcpservaddr (char *host, char *port, struct sockaddr_in *psa) { /* *psa an Internet endpoint address */ struct hostent *phe; /* pointer to host information entry */ struct servent *pse; /* pointer to service information entry */ psa->sin_family = AF_INET; if (pse = getservbyname(port,"tcp")) psa->sin_port = pse->s_port; else if ((psa->sin_port = htons((unsigned short)atoi(port))) == 0) { return 2; } if (host == NULL || *host == 0 || strcasecmp(host,"inaddrany") == 0 || strcasecmp(host,"inaddr_any") == 0 || strcasecmp(host,"255.255.255.255") == 0 || strcasecmp(host,"0.0.0.0") == 0 ) psa->sin_addr.s_addr = INADDR_ANY; else if (phe = gethostbyname(host)) memcpy (&(psa->sin_addr),phe->h_addr, phe->h_length); else if ((psa->sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { return 1; } return 0; // OK } 

It fills the struct sockaddr_in with the IP address and port number. Call:

 struct sockaddr_in addr; ... switch (make_tcpservaddr(host, port, &addr)) { case 0: break; // OK .... } 

Then you can use the addr structure either to connect the client to the server

 if (connect(cli_sock,(struct sockaddr *)&addr,sizeof(addr)) < 0) { perror("connect"); } 

either for server

 if (bind(serv_sock,(struct sockaddr *)&addr,sizeof(addr)) < 0) { perror ("bind"); } 

Obviously, error handling may be different. For example, for the server, in the case of errno == EADDRINUSE, several attempts can be made bind ()

Regarding ESMTP / SMTP conversation (port 25)

First, always check the server response code (the first 3 characters are the response code). If the first character of answer 2 is normal.

Always check for the word ESMTP in the server greeting. If it does not exist (now you can hardly see it, but still ...), then the SMTP protocol, and not ESMTP. For the SMTP protocol, you must answer with the HELO line, and for ESMTP, the EHLO.

Here is an example (as you can see the login-password is not at all mandatory. Its necessity is revealed during the initial dialogue with the server)

 220 mail.bigtelecom.ru ESMTP Postfix ehlo scan.ru 250-mail.bigtelecom.ru 250-PIPELINING 250-SIZE 30720000 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN mail from: avp@scan.ru 250 2.1.0 Ok quit 221 2.0.0 Bye 

Well, here read the RFC for SMTP / ESMTP

A couple of important notes. Mail protocol is string oriented . End dates are 2 characters \ r \ n. But, some clients (and possibly servers) in practice neglect the \ r symbol (and sometimes). This must be considered when parsing the protocol.

The second is also associated with string orientation. The recv () function (unfortunately) can return either a part of a string or several lines. Therefore, you will have to translate the received data into a stream of lines (well, or do fdopen () (it works strangely only in Windows - an incentive to drop it)).

Successes. Ask if I remember anything else about the mail - I will help.

Base64 encoding-decoding functions with multiple call options from main (in #if ... #else ... #endif).

 #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32 typedef unsigned char u_char; #endif /* If the user agent wishes to send the userid "Aladdin" and password "open sesame", it would use the following header field: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== http://base64.sourceforge.net/b64.c */ /* ** Translation Table as described in RFC1113 */ static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // 3 bytes (len) to 4 base64 bytes void encode_b64block (u_char *in, u_char *out, int len) { out[0] = cb64[in[0] >> 2]; out[1] = cb64[((in[0] << 4) | (in[1] >> 4)) & 0x3f]; out[2] = (len > 1) ? cb64[((in[1] << 2) | (in[2] >> 6)) & 0x3f] : '='; out[3] = (len > 2) ? cb64[in[2] & 0x3f] : '='; } /* Кодирует ilen байт в base64 Returns: количество байт, помещенных в b64out (max oblen) в *ires количество закодированых байт из inpch8 */ int encode_b64 (u_char *inpch8, int ilen, u_char *b64out, int oblen, int *ires) { int i, l = 0, bound = (oblen/4)*3; // байты входа, размещаемые в выходе if (bound > ilen) bound = ilen; bound = (bound/3)*3; for (i = 0; i < bound; i += 3, l += 4) { encode_b64block (inpch8+i, b64out+l, 3); } if (i < ilen) { if (oblen-l > 3) { int len = ilen-i; encode_b64block (inpch8+i, b64out+l, len); l += 4; if (len > 2) i += 3; else if (len > 1) i += 2; else i++; } } if (ires) *ires = i; return l; } static u_char decodetab[256]; static int initdecode = 0; // 4 (len) base64 bytes to 8-bit bytes. // Returns number of output bytes int decode_b64block (u_char *in, u_char *out, int len) { if (len < 2 || in[0] == '=' || in[1] == '=' || in[0] == 0 || in[1] == 0) return 0; if (!initdecode) { int i; for (i = 0; i < 256; i++) decodetab[i] = 0xff; for (i = 0; cb64[i]; i++) decodetab[(u_char)cb64[i]] = i; initdecode = 1; } out[0] = (decodetab[in[0]] << 2) | (decodetab[in[1]] >> 4); if (len == 2 || in[2] == '=' || in[2] == 0) return 1; out[1] = (decodetab[in[1]] << 4) | (decodetab[in[2]] >> 2); if (len == 3 || in[3] == '=') return 2; out[2] = (decodetab[in[2]] << 6) | decodetab[in[3]]; return 3; } // 4 (len) decodetab[] base64 bytes to 8-bit bytes. // Returns number of output bytes int decode_true_b64block (u_char *in, u_char *out, int len) { if (len < 2) return 0; out[0] = (in[0]<<2) | (in[1] >> 4); if (len == 2) return 1; out[1] = (in[1]<<4) | (in[2]>>2); if (len == 3) return 2; out[2] = (in[2]<<6) | in[3]; return 3; } // decode up to '=' or '\0' skipping "garbage" // Returns output length int decode_b64str (u_char *inb64, u_char *out, int olmax, u_char **endinp) { int i, len = 0, bound = olmax-3, go = 1, l; if (!initdecode) { for (i = 0; i < 256; i++) decodetab[i] = 0xff; for (i = 0; cb64[i]; i++) decodetab[(u_char)cb64[i]] = i; initdecode = 1; } u_char ib[4]; while (go) { for (l = 0; l < 4;) { if (*inb64 == '=' || !*inb64) { go = 0; break; } if ((ib[l] = decodetab[*inb64++]) < 128) l++; } if (len < bound) len += decode_true_b64block(ib,out+len,l); else { u_char ob[3]; int lb = decode_true_b64block(ib,ob,l); int lm = olmax-len; if (lm > lb) lm = lb; for (i = 0; i < lm; i++) out[len++] = ob[i]; break; } } if (endinp) *endinp = inb64; return len; } // base64 encode a stream adding padding and line breaks void b64_file_encode( FILE *in, FILE *out, int lsize, char *eol ) { u_char inb[3], outb[4]; int i, len, blocks = 0; if (lsize < 1) lsize = 76; if (!eol) eol = "\n"; while(!feof(in)) { len = 0; for (i = 0; i < 3; i++) { inb[i] = getc (in); if (!feof(in)) { len++; } else { inb[i] = 0; } } if (len) { encode_b64block (inb,outb,len); for (i = 0; i < 4; i++) { putc (outb[i],out); } blocks++; } if (blocks >= (lsize/4) || feof(in)) { if (blocks) fputs (eol,out); blocks = 0; } } } // decode a base64 encoded stream discarding padding, line breaks and noise void b64_file_decode (FILE *in, FILE *out) { u_char buf[4097]; int l; while (fgets((char *)buf,4097,in)) { l = decode_b64str (buf,buf,4097,NULL); fwrite (buf,1,l,out); } } #if 0 main () { // decode (stdin,stdout); u_char x = 0xf1; u_char y = (x>>4); char *in = "Ala"; char out[10]; out[4] = 0; int l = strlen(in); encode_b64block (in,out,l); printf ("%s\n",out); out[4] = ' '; out[9] = 0; l = decode_b64block (out,out+5,4); out[5+l] = 0; printf ("l = %d [%s]\n",l,out); char outp[100]; u_char *last; int ls = decode_b64str (" QWxhZGRpbjpvcGVuIHNlc2FtZQ==",outp,19,&last); outp[ls] = 0; printf ("decode_b64str %d <%s> [%c]\n",ls,outp,*last); char b64[100]; int ic, lb64 = encode_b64 (outp,ls,b64,100,&ic); b64[lb64] = 0; printf ("encode_b64 = %d <%s> %d\n",lb64,b64,ic); } #else main () { char buf[1000]; #if 0 while (fgets(buf,1000,stdin)) { int l = decode_b64str(buf,buf,999,NULL); write (1,buf,l); } #else // b64_file_decode (stdin,stdout); b64_file_encode(stdin,stdout,0,0); #endif } #endif 

I hope it will be useful.

  • > Transferred code from comments and removed errors that were well in the eye rushed .. I tried to compile the code D: \ CREATE ~ 1 \ C__ ~ 1 \ Mail \ mail.cpp: In function int main()': D:\CREATE~1\C__~1\Mail\mail.cpp:17: request for member resize 'in text', which is of non-aggregate type char [1025] 'Failure - ananas
  • @ananas, not quite understood, but if about my function, then c: / Users / avp / src / cc / hashcode $ gcc -c ts.cc:/Users/avp/src/cc/hashcode $ c: / Users / avp / src / cc / hashcode $ g ++ -c ts.cc:/Users/avp/src/cc/hashcode $ c: / Users / avp / src / cc / hashcode $ g ++ --version g ++. exe (GCC) 3.4 .5 (mingw-vista special r3) Copyright (C) 2004 Free Software Foundation, Inc. As you can see, both g ++ and gcc are normally perceived in Windows 7 MinGW. In Linux, too, OK. What are you working in? - avp
  • > It was a comment for lirik90 I am writing in c ++ for the gcc.exe console -v 2.95.2 19991024 under Windows XP - ananas
  • @ananas, try with winsock.h instead of winsock2.h (only these are not libraries, but header files , but the name is not in the name). Perhaps in your version (supply) of gcc all the necessary structures and constants are described there. If not, look, maybe among your "system" users there are the same as for * nix. - avp

Transferred code from comments and removed errors that were well in the eye rushed ..

 #include <conio.h> #include <iostream> #include <string> #include <winsock.h> int main() { WSADATA ws; SOCKET s; struct sockaddr_in addr; hostent *d_addr; char text[1024 + 1]; int result; text.resize(1024); char * cstr; string str1,str2,str3; //инициализируем сокеты if (FAILED (WSAStartup (MAKEWORD(1,1), &ws))) { printf("Error in WSAStartup(...)\n"); return 1; } //создаем сокет s = socket (AF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { printf("Error in socket(...)\n"); WSACleanup(); return 1; } //получаем адрес сервера d_addr = gethostbyname ("smtp.yandex.ru"); if (d_addr == NULL) { printf("Error in gethostbyname(...)\n"); closesocket(s); WSACleanup(); return 1; }; //заполняем параметры адреса addr.sin_family = AF_INET; addr.sin_addr.s_addr = ((unsigned long ) d_addr->h_addr); addr.sin_port = htons (25); //устанавливаем соединение if (SOCKET_ERROR == (connect (s, (sockaddr *) &addr, sizeof (addr)))) { printf("Error in connect(...)\n"); closesocket(s); WSACleanup(); return 1; } //ждем ответ от сервера result = recv(s, text, 1024, 0); if (result <= 0) { printf("Error recv\n"); closesocket(s); WSACleanup(); return 1; } text[result] = 0; printf("recv - %s", text); //приветствуем сервер strcpy(text, "EHLO smtp.yandex.ru \r\n"); send(s, text, strlen(text), 0); printf("send - %s", text); strcpy(text, "AUTH LOGIN\r\n"); send(s, text, strlen(text), 0); //НУ И ЧТО ВЫ ЗДЕСЬ ОТПРАВЛЯЕТЕ ??? strcpy(text,"логин в base64\r\n"); send(s, text, strlen(text), 0); //и здесь "ЧТО ОТПРАВЛЯЕТЕ ???" strcpy(text, "пароль в base64\r\n"); send(s, text,strlen(text),0); //ждем подтверждение от сервера result = recv(s, text, 1024, 0); if (result <= 0) { printf("Error recv\n"); closesocket(s); WSACleanup(); return 1; } text[result] = 0; printf("recv - %s", text); //сообщаем отправителя str1 = "MAIL FROM: "; cout << "mail otpravitelya: "; cin >> str2; str1 += str2; str1 += "\r\n"; send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //ждем подтверждение от сервера result = recv(s, text, 1024, 0); if (result <= 0) { printf("Error recv\n"); closesocket(s); WSACleanup(); return 1; } text[result] = 0; printf("recv - %s", text); //сообщаем получателя str1 = "RCPT TO: "; cout << "mail poluchatelya: "; cin >> str3; str1 += str2; str1 += "\r\n"; send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //ждем подтверждение от сервера recv(s,text,sizeof(text),0); printf("recv - %s", text); //подаем команду, что готовы начать передачу письма strcpy(text,"DATA\r\n"); send(s,text,strlen(text),0); printf("send - %s", text); //ждем подтверждение от сервера recv(s,text,sizeof(text),0); printf("recv - %s", text); //передаем заголовок //от кого письмо str1 = "FROM: "; cout << "mail otpravitelya: "; cin >> str2; str1 += str2; str1 += "\r\n"; //Тут чаго ??? send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //кому письмо str1 = "TO: "; str1 += str2; str1 += "\r\n"; send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //тема письма str1 = "SUBJECT: "; cout << "Tema mail: "; cin >> str2; str1 += str2; str1 += "\r\n\r\n"; send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //текст письма cout << "Text: "; cin >> str1; str1 += "\n"; send(s, str1.c_str(), str1.length(), 0); printf("send - %s", cstr); //говорим, что закончили strcpy(text, "\r\n.\r\n"); send(s,text,strlen(text),0); printf("send - %s", text); result = recv(s,text,sizeof(text),0); if (result <= 0) { printf("Error recv\n"); closesocket(s); WSACleanup(); return 1; } text[result] = 0; printf("recv - %s", text); //прощаемся с сервером send(s,"QUIT", 4,0); printf("send - QUIT"); //закрываем сокет closesocket(s); //деинициализирует сервис WSACleanup(); printf("\n"); printf("Press any key\n"); getch(); return 0; } 
  • Well, at least after recv, it would not be bad to check for errors, and that for example, if the password is not correct or there is no such user, in my example, the idea above was clear ... and if you write in c ++, then there is such a cool thing , "classes" is called;) since I really want to overcome the SMTP client, stick your little class, otherwise it’s even worse than my post is higher)) - lirik90
  • Oooooh brrrrr)))) how much new [] and how little delete [] =))))) - lirik90
  • recv (s, text, sizeof (text), 0); what is this ? Have you checked what sizeof (text) will return to you?) In fact, you would have read some little book =) - lirik90
  • one
    @ananas, well, everything is really bad, at least, compare it with "this" with your code "from comments" and look at the difference which you don’t need to do at all)) For example, if you allocate memory char * var = new char [1024] ; you need to release it !!! etc ...... - lirik90
  • > recv (s, text, sizeof (text), 0); what is this? Have you checked what sizeof (text) will return to you? The description says the sizeof operator returns the size in bytes of an object or data type. Do I understand correctly, in my case, this is the size of the array of characters in bytes, and in recv you need a buffer length that is measured in the number of characters. In order for the recv function to determine the number of characters in the text array itself, you need to replace it with another function that will calculate the length not in bytes, but in the number of characters? As I understand it, if you manually set this number, if you enter more than this number of characters, there will be an error due to buffer overflow - ananas

I apologize for the code in this form.

 strcpy(text,"логин в base64\r\n"); send(s, text, strlen(text), 0); 

In this place, I translate my login into base64 with a program, then insert it into the code, compile it. Yes, it is not very convenient for each address to compile the program. For the password is similar. I just wanted to create a separate question in order to enter the login and password when connecting via the console, and the function that will become the result will translate the text from the console into base64 and paste it into the place indicated above.

  • one
    At this point you could already use the base64_encode function from my example, did you even run it? all you need is to download the source open it in visual studio click in the Project-> Properties menu there to go to debugging and in the "Command Arguments" line correct the command line parameters according to your account on the smtp server;), and then (THIS IMPORTANT) press F11 and clap F11 until the program finishes (periodically looking at the “Local” table), and I’m almost sure that after that it will be easier for you)) - lirik90
  • I also plan to use base64_encode, but I do not have one yet. Ваш exe я запускал консоль появляется на 1с и исчезает, ничего не происходит. исходник при компиляции выдает D:\CREATE~1\C__~1\smtp\smtp.cpp:3: WinSock2.h: No such file or directory т.к. у меня есть только библиотеки winsock, winsock2 нашел только для VS Исходник только с void base64_encode выдает d:\gcc\bin\..\lib\gcc-lib\libmingw32.a(main.o)(.text+0x8e): undefined reference to 'WinMain@16'ananas
  • Исходник как я понял для VS, с ней я еще не работал, так как пробую писать на c++ для консоли gcc.exe -v 2.95.2 19991024, думаю чтобы не запутаться в 2 программах.ananas