SOCKET'S

Тема в разделе "WASM.WIN32", создана пользователем arajan, 9 янв 2005.

  1. arajan

    arajan New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    1
    Адрес:
    Russia
    Добрый день.



    Есть код. Написан моими кривыми руками после прочтения статьи ИСПОЛЬЗОВАНИЕ СОКЕТОВ/ВЗАИМОДЕЙСТВИЕ С SMTP СЕРВЕРАМИ.



    Задача: отправить письмо любого содержания через smtp.



    Есть несколько проблем:



    1. Почему не проходит комманда MAIL FROM: arajan@mail.ru?

    Самое интересное, что он даже не добирается до условия. Просто процесс работает а действий никаких. Может проблема в том что ответ не получен??? Не знаю...



    2. Как посылать эти CRLF-ы???? Правильно ли я делаю у себя в программе???




    Код (Text):
    1.    
    2.     .486
    3.     .model flat, stdcall
    4.     option casemap :none
    5. ;
    6.     include \masm32\include\windows.inc
    7.     include \masm32\include\masm32.inc
    8.     include \masm32\include\kernel32.inc
    9.     include \masm32\include\wininet.inc
    10.     include \masm32\include\ws2_32.inc
    11.     include \masm32\macros\my_macros.asm
    12. ;
    13.     includelib \masm32\lib\masm32.lib
    14.     includelib \masm32\lib\kernel32.lib
    15.     includelib \masm32\lib\wininet.lib
    16.     includelib \masm32\lib\ws2_32.lib
    17. ;ДАННЫЕ
    18. .data                                                   ; определенные
    19. ;данные сервера
    20.     ServerIP        db          "194.67.23.111",0       ; ip адрес smtp.mail.ru
    21.     Port            dd          25
    22. ;общение с сервером
    23.     _HELO_          db          "HELO server.com",'$'
    24.     _LEN_HELO_      =           $ - _HELO_
    25.     _MAIL_FROM_     db          "MAIL FROM: arajan@mail.ru",0
    26.     _LEN_MAIL_FROM_ =           $ - _MAIL_FROM_
    27.     _RCPT_TO_       db          "RCPT TO: arajan@omen.ru",'$'
    28.     _LEN_RCPT_TO_   =           $ - _RCPT_TO_
    29.     _DATA_          db          "DATA",'$'
    30.     _LEN_DATA_      =           $ - _DATA_
    31.     _LETTER_        db          "This is a socket test letter.",'$'
    32.     _LEN_LETTER_    =           $ - _LETTER_
    33.     _POINT_         db          ".",'$'
    34.     _LEN_POINT_     =           $ - _POINT_
    35.     _QUIT_          db          "QUIT",'$'
    36.     _LEN_QUIT_      =           $ - _QUIT_
    37.     _CRLF_          db          "CRLF",'$'
    38.     _LEN_CRLF_      =           $ - _CRLF_
    39. ;
    40. .data?                                                  ; не определенные
    41. ;
    42.     WSAData         WSADATA     <?>
    43.     SoketHandle     dd          ?
    44.     sin             sockaddr_in <?>
    45.     TEMP            db          ?
    46.     BUFF            dd          ?
    47. ;
    48. ;КОД ПРОГРАММЫ
    49. .code
    50. ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\
    51. start:
    52. ; main
    53. _main proc
    54.     _START:
    55.         print   "Start procces."
    56.         invoke  InternetGetConnectedState, 0, 0                         ; проверка наличия соединения с интернетом
    57.         .if eax == 0
    58.             print "ERROR: Can't find internet connection."
    59.             jmp _END
    60.         .endif
    61.         print "Programm find internet connection."
    62.         invoke  WSAStartup, 0101h, addr WSAData                         ; инициализируем работу с winsocks.dll
    63.         .if eax != 0                                                    ; проверка инициализации
    64.             print "ERROR: Can't do WSAStartup."
    65.             jmp _END
    66.         .endif
    67.         print "WSAStartup."
    68.         .if word ptr WSAData.wVersion != 0101h                          ; проверка версии wsock
    69.             print "ERROR: Wsock version != 1.1."
    70.             jmp _CLEAR_SOCK
    71.         .endif
    72.         print "Wsock version = 1.1."
    73.         invoke socket, AF_INET, SOCK_STREAM, 0                                          ; открытие сокета
    74.         .if eax == INVALID_SOCKET                                                       ; проверка что сокет открыт
    75.             print "ERROR: Can't open Socket."
    76.             jmp _CLEAR_SOCK
    77.         .endif
    78.         mov     dword ptr SoketHandle       ,eax
    79.         print   "Socket open."
    80.         mov     sin.sin_family              ,AF_INET                                    ; заполняем структуру sin
    81.         invoke  htons ,Port                                                             ; конвертируем порт в сетевой порядок байтов
    82.         mov     sin.sin_port                ,ax                                         ; заполняем структуру sin
    83.         invoke  inet_addr , addr ServerIP                                               ; конвертируем порт в сетевой порядок байтов
    84.         mov     sin.sin_addr                ,eax                                        ; заполняем структуру sin
    85.         invoke  connect ,dword ptr [SoketHandle] ,addr sin ,sizeof sin                  ; устанавливаем соединение с ServerIP
    86.         .if eax == SOCKET_ERROR                                                         ; проверка успешного соединения
    87.             print "ERROR: Conection falied."
    88.             jmp _CLOSE_SOCK
    89.         .endif
    90.         print "Connected."
    91.         ;ОБЩЕНИЕ С SMTP СЕРВЕРОМ
    92.         ;
    93.         invoke  send, dword ptr [SoketHandle], addr _HELO_, _LEN_HELO_, 00h             ; посылаем HELO server.com
    94.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    95.         print "HELO server.com"
    96.         call _recv
    97.         .if eax != 20303232h
    98.         ;.if eax != 32323020h                                                           ; ожидаемый ответ сервера "220 "
    99.             print "ERROR: HELO server.com."
    100.             jmp _CLOSE_SOCK
    101.         .endif
    102.         print "OK. 220."
    103.         ;
    104.         invoke  send, dword ptr [SoketHandle], addr _MAIL_FROM_, _LEN_MAIL_FROM_, 00h   ; посылаем MAIL FROM: arajan@mail.ru
    105.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    106.         print "MAIL FROM: arajan@mail.ru"
    107.         call _recv
    108.         .if eax != 20303532h                                                            ; ожидаемый ответ сервера "250 "
    109.         ;.if eax != 32353020h                                                           ; ожидаемый ответ сервера "250 "
    110.             print "ERROR: MAIL FROM: arajan@mail.ru."
    111.             jmp _CLOSE_SOCK
    112.         .endif
    113.         print "OK. 250."
    114.         ;
    115.         invoke  send, dword ptr [SoketHandle], addr _RCPT_TO_, _LEN_RCPT_TO_, 00h       ; посылаем RCPT TO: arajan@omen.ru
    116.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    117.         print "RCPT TO: arajan@omen.ru"
    118.         call _recv
    119.         .if eax != 20303532h                                                            ; ожидаемый ответ сервера "250 "
    120.         ;.if eax != 32353020h                                                           ; ожидаемый ответ сервера "250 "
    121.             print "ERROR: RCPT TO: arajan@omen.ru."
    122.             jmp _CLOSE_SOCK
    123.         .endif
    124.         print "OK. 250."
    125.         ;
    126.         invoke  send, dword ptr [SoketHandle], addr _DATA_, _LEN_DATA_, 00h             ; посылаем DATA
    127.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    128.         print "DATA"
    129.         call _recv
    130.         .if eax != 20343533h                                                            ; ожидаемый ответ сервера "354 "
    131.         ;.if eax != 33353420h                                                           ; ожидаемый ответ сервера "354 "
    132.             print "ERROR: DATA."
    133.             jmp _CLOSE_SOCK
    134.         .endif
    135.         print "OK. 250."
    136.         ;
    137.         invoke  send, dword ptr [SoketHandle], addr _LETTER_, _LEN_LETTER_, 00h         ; посылаем само письмо
    138.         print "This is a socket test letter."
    139.         ;
    140.         invoke  send, dword ptr [SoketHandle], addr _POINT_, _LEN_POINT_, 00h           ; посылаем .
    141.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    142.         print "."
    143.         call _recv
    144.         .if eax != 20303532h                                                            ; ожидаемый ответ сервера "250 "
    145.         ;.if eax != 32353020h                                                           ; ожидаемый ответ сервера "250 "
    146.             print "ERROR: ."
    147.             jmp _CLOSE_SOCK
    148.         .endif
    149.         print "OK. 250."
    150.         ;
    151.         invoke  send, dword ptr [SoketHandle], addr _QUIT_, _LEN_POINT_, 00h            ; посылаем QUIT
    152.         invoke  send, dword ptr [SoketHandle], addr _CRLF_, _LEN_CRLF_, 00h             ; +CRLF
    153.         print "QUIT"
    154.         print "OK. Connection closed."
    155.         ;
    156.     _CLOSE_SOCK:
    157.         invoke  closesocket         ,dword ptr [SoketHandle]            ; закрытие сокета
    158.         print "Socket close."
    159.     _CLEAR_SOCK:
    160.         invoke  WSACleanup                                              ; прекращение использования winsocks.dll
    161.         print "WSACleanup."
    162.     _END:
    163.         print "Exit process."
    164.         exit
    165. _main endp
    166. ;процедура приема из сокета
    167. _recv proc
    168. ;   на входе:
    169. ;       Hичего.
    170. ;   на выходе:
    171. ;       EAX = В случае успеха пеpвые полученные 4 байта, иначе 0.
    172. ;
    173.         invoke  recv, dword ptr [SoketHandle], addr BUFF, 04h, 00h
    174.         inc     eax                                                         ; проверяем наличие ошибки (-1)
    175.         jz      recv_err
    176.         cmp     eax,5
    177.         jnz     recv_err
    178.         mov     TEMP    ,00h
    179.     get1mo:                                                                 ; считываем все что нам шлет сервер
    180.         invoke  recv, dword ptr [SoketHandle], addr TEMP, 01h, 00h
    181.         cmp     byte ptr [TEMP],0Ah                                         ; пока не найдем символ окончания строки
    182.         jnz     get1mo
    183.         mov     eax     ,dword ptr [BUFF]                                   ; EAX = полученное двойное слово
    184.         ret
    185.     recv_err:
    186.         mov     eax     ,0
    187.         ret
    188. ;
    189. _recv endp
    190. ;
    191. end start
    192.  




    Заранее благодарен за помощь.



    ps: Я понимаю что нет ничего хуже копаться в чужом коде. Вы меня очень сильно выручите.
     
  2. hello_world

    hello_world New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2003
    Сообщения:
    55
    Адрес:
    москва
    мда-а...



    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, может быть поможет.



    [​IMG] 814771265__sendmail.inc
     
  3. Artix

    Artix New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2005
    Сообщения:
    9
    я бы тебе посоветавал делать неблокирующие сокеты на recv, чтобы если сервер глюкнет или коннект кривой не произошло зависания программы



    при блокирующий прога будет ждать recv но не дождется.....

    ioctlsocket функция, первый параметр сокет, второй там констата помоему, и третий для неблокирующий 1, потом для блока 0



    то есть делаешь

    1. send

    2. Разблокируешь

    3. Ждешь события от сокета, select функция

    4. Получаешь если все прошло удачно



    И тогда ты сможешь понять где у тебя прога зависает