Добрый день. Есть код. Написан моими кривыми руками после прочтения статьи ИСПОЛЬЗОВАНИЕ СОКЕТОВ/ВЗАИМОДЕЙСТВИЕ С SMTP СЕРВЕРАМИ. Задача: отправить письмо любого содержания через smtp. Есть несколько проблем: 1. Почему не проходит комманда MAIL FROM: arajan@mail.ru? Самое интересное, что он даже не добирается до условия. Просто процесс работает а действий никаких. Может проблема в том что ответ не получен??? Не знаю... 2. Как посылать эти CRLF-ы???? Правильно ли я делаю у себя в программе??? Код (Text): .486 .model flat, stdcall option casemap :none ; include \masm32\include\windows.inc include \masm32\include\masm32.inc include \masm32\include\kernel32.inc include \masm32\include\wininet.inc include \masm32\include\ws2_32.inc include \masm32\macros\my_macros.asm ; includelib \masm32\lib\masm32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\wininet.lib includelib \masm32\lib\ws2_32.lib ;ДАННЫЕ .data ; определенные ;данные сервера ServerIP db "194.67.23.111",0 ; ip адрес smtp.mail.ru Port dd 25 ;общение с сервером _HELO_ db "HELO server.com",'$' _LEN_HELO_ = $ - _HELO_ _MAIL_FROM_ db "MAIL FROM: arajan@mail.ru",0 _LEN_MAIL_FROM_ = $ - _MAIL_FROM_ _RCPT_TO_ db "RCPT TO: arajan@omen.ru",'$' _LEN_RCPT_TO_ = $ - _RCPT_TO_ _DATA_ db "DATA",'$' _LEN_DATA_ = $ - _DATA_ _LETTER_ db "This is a socket test letter.",'$' _LEN_LETTER_ = $ - _LETTER_ _POINT_ db ".",'$' _LEN_POINT_ = $ - _POINT_ _QUIT_ db "QUIT",'$' _LEN_QUIT_ = $ - _QUIT_ _CRLF_ db "CRLF",'$' _LEN_CRLF_ = $ - _CRLF_ ; .data? ; не определенные ; WSAData WSADATA <?> SoketHandle dd ? sin sockaddr_in <?> TEMP db ? BUFF dd ? ; ;КОД ПРОГРАММЫ .code ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\ start: ; main _main proc _START: print "Start procces." invoke InternetGetConnectedState, 0, 0 ; проверка наличия соединения с интернетом .if eax == 0 print "ERROR: Can't find internet connection." jmp _END .endif print "Programm find internet connection." invoke WSAStartup, 0101h, addr WSAData ; инициализируем работу с winsocks.dll .if eax != 0 ; проверка инициализации print "ERROR: Can't do WSAStartup." jmp _END .endif print "WSAStartup." .if word ptr WSAData.wVersion != 0101h ; проверка версии wsock print "ERROR: Wsock version != 1.1." jmp _CLEAR_SOCK .endif print "Wsock version = 1.1." invoke socket, AF_INET, SOCK_STREAM, 0 ; открытие сокета .if eax == INVALID_SOCKET ; проверка что сокет открыт print "ERROR: Can't open Socket." jmp _CLEAR_SOCK .endif mov dword ptr SoketHandle ,eax print "Socket open." mov sin.sin_family ,AF_INET ; заполняем структуру sin invoke htons ,Port ; конвертируем порт в сетевой порядок байтов mov sin.sin_port ,ax ; заполняем структуру sin invoke inet_addr , addr ServerIP ; конвертируем порт в сетевой порядок байтов mov sin.sin_addr ,eax ; заполняем структуру sin invoke connect ,dword ptr [SoketHandle] ,addr sin ,sizeof sin ; устанавливаем соединение с ServerIP .if eax == SOCKET_ERROR ; проверка успешного соединения print "ERROR: Conection falied." jmp _CLOSE_SOCK .endif print "Connected." ;ОБЩЕНИЕ С SMTP СЕРВЕРОМ ; invoke send, dword ptr [SoketHandle], addr _HELO_, _LEN_HELO_, 00h ; посылаем HELO server.com invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "HELO server.com" call _recv .if eax != 20303232h ;.if eax != 32323020h ; ожидаемый ответ сервера "220 " print "ERROR: HELO server.com." jmp _CLOSE_SOCK .endif print "OK. 220." ; invoke send, dword ptr [SoketHandle], addr _MAIL_FROM_, _LEN_MAIL_FROM_, 00h ; посылаем MAIL FROM: arajan@mail.ru invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "MAIL FROM: arajan@mail.ru" call _recv .if eax != 20303532h ; ожидаемый ответ сервера "250 " ;.if eax != 32353020h ; ожидаемый ответ сервера "250 " print "ERROR: MAIL FROM: arajan@mail.ru." jmp _CLOSE_SOCK .endif print "OK. 250." ; invoke send, dword ptr [SoketHandle], addr _RCPT_TO_, _LEN_RCPT_TO_, 00h ; посылаем RCPT TO: arajan@omen.ru invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "RCPT TO: arajan@omen.ru" call _recv .if eax != 20303532h ; ожидаемый ответ сервера "250 " ;.if eax != 32353020h ; ожидаемый ответ сервера "250 " print "ERROR: RCPT TO: arajan@omen.ru." jmp _CLOSE_SOCK .endif print "OK. 250." ; invoke send, dword ptr [SoketHandle], addr _DATA_, _LEN_DATA_, 00h ; посылаем DATA invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "DATA" call _recv .if eax != 20343533h ; ожидаемый ответ сервера "354 " ;.if eax != 33353420h ; ожидаемый ответ сервера "354 " print "ERROR: DATA." jmp _CLOSE_SOCK .endif print "OK. 250." ; invoke send, dword ptr [SoketHandle], addr _LETTER_, _LEN_LETTER_, 00h ; посылаем само письмо print "This is a socket test letter." ; invoke send, dword ptr [SoketHandle], addr _POINT_, _LEN_POINT_, 00h ; посылаем . invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "." call _recv .if eax != 20303532h ; ожидаемый ответ сервера "250 " ;.if eax != 32353020h ; ожидаемый ответ сервера "250 " print "ERROR: ." jmp _CLOSE_SOCK .endif print "OK. 250." ; invoke send, dword ptr [SoketHandle], addr _QUIT_, _LEN_POINT_, 00h ; посылаем QUIT invoke send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h ; +CRLF print "QUIT" print "OK. Connection closed." ; _CLOSE_SOCK: invoke closesocket ,dword ptr [SoketHandle] ; закрытие сокета print "Socket close." _CLEAR_SOCK: invoke WSACleanup ; прекращение использования winsocks.dll print "WSACleanup." _END: print "Exit process." exit _main endp ;процедура приема из сокета _recv proc ; на входе: ; Hичего. ; на выходе: ; EAX = В случае успеха пеpвые полученные 4 байта, иначе 0. ; invoke recv, dword ptr [SoketHandle], addr BUFF, 04h, 00h inc eax ; проверяем наличие ошибки (-1) jz recv_err cmp eax,5 jnz recv_err mov TEMP ,00h get1mo: ; считываем все что нам шлет сервер invoke recv, dword ptr [SoketHandle], addr TEMP, 01h, 00h cmp byte ptr [TEMP],0Ah ; пока не найдем символ окончания строки jnz get1mo mov eax ,dword ptr [BUFF] ; EAX = полученное двойное слово ret recv_err: mov eax ,0 ret ; _recv endp ; end start Заранее благодарен за помощь. ps: Я понимаю что нет ничего хуже копаться в чужом коде. Вы меня очень сильно выручите.
мда-а... 1) CRLF equ 0dh,0ah т.е. перевод строки и возврат каретки. 2) айпишник у мейл.ру может и поменяться, так что делай gethostbyname("smtp.mail.ru") 3) нафига везде символ доллара ??? 4) мейл.ру позволяет посылать с локальных адресов без пароля, но обычно везде используется ESMTP 5) htons юзать не надо. Это просто mov ax,port xchg al,ah 6) не надо делать send 2 раза подряд. 7) recv тоже 8) результат recv'а выводи на экран, чтобы видеть что происходит. Или сниффер поставь. 9) перед тем как че-то писать пошли письмо телнетом. Т.е. telnet smtp.mail.ru 25 10) прочитай эти рфц: rfc 2821 rfc 822 rfc 2045 rfc 2554 Вот наверно и все В аттаче моя ф-я SendMail, может быть поможет. 814771265__sendmail.inc
я бы тебе посоветавал делать неблокирующие сокеты на recv, чтобы если сервер глюкнет или коннект кривой не произошло зависания программы при блокирующий прога будет ждать recv но не дождется..... ioctlsocket функция, первый параметр сокет, второй там констата помоему, и третий для неблокирующий 1, потом для блока 0 то есть делаешь 1. send 2. Разблокируешь 3. Ждешь события от сокета, select функция 4. Получаешь если все прошло удачно И тогда ты сможешь понять где у тебя прога зависает