WinSock TCP

Тема в разделе "WASM.NETWORKS", создана пользователем hiho, 7 янв 2012.

  1. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Попробовал переписать на масм код Криса для создания сокетов, не ожидал, что возникнут проблемы, вроде же один API
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\wsock32.inc
    7. include \masm32\include\user32.inc
    8. include \masm32\include\kernel32.inc
    9. include \masm32\include\shell32.inc
    10.  
    11. includelib \masm32\lib\user32.lib
    12. includelib \masm32\lib\kernel32.lib
    13. includelib \masm32\lib\wsock32.lib
    14. includelib \masm32\lib\shell32.lib
    15.  
    16. CreateSocket PROTO :DWORD
    17.  
    18. .DATA
    19.     WSA         WSADATA <>
    20. .CODE
    21.  
    22. start:
    23.  
    24.     ; Шаг 1 - Инициализация Библиотеки Сокетов
    25.    
    26.     INVOKE WSAStartup, 202h, addr WSA
    27.     .IF (EAX)
    28.         JMP JErr;
    29.     .ENDIF
    30.     INVOKE CreateSocket, 6677
    31.     JErr:
    32.         INVOKE WSACleanup
    33.         INVOKE ExitProcess, 0      
    34.  
    35. ClientThread PROC Sock  : SOCKET
    36.     LOCAL Bytes         : DWORD
    37.     LOCAL BufStr[1024]  : BYTE
    38.     .REPEAT
    39.         INVOKE recv, Sock, addr BufStr, sizeof BufStr, 0
    40.         MOV Bytes, EAX
    41.         INVOKE MessageBox,0,addr BufStr,0,0
    42.     .UNTIL (Bytes <= 0)
    43.     INVOKE closesocket, Sock
    44. ClientThread ENDP
    45.  
    46. CreateSocket PROC Port :DWORD
    47.     LOCAL Sock      : SOCKET
    48.     LOCAL Client    : SOCKET
    49.     LOCAL sin       : sockaddr_in
    50.     LOCAL thID      : DWORD
    51.  
    52.     ; Шаг 2 - создание сокета
    53.    
    54.     INVOKE socket, AF_INET, SOCK_STREAM, 0
    55.     .IF (EAX < 0)
    56.         JMP JErr;
    57.     .ENDIF
    58.    
    59.     ;Шаг 3 - связывание сокета с локальным адресом
    60.    
    61.     MOV Sock, EAX                                
    62.     MOV sin.sin_family, AF_INET
    63.     INVOKE htons, Port
    64.     MOV sin.sin_port, AX
    65.     MOV sin.sin_addr, INADDR_ANY
    66.  
    67.     ; Вызываем bind для связывания
    68.  
    69.     INVOKE bind, Sock, addr sin, sizeof sin
    70.     .IF (EAX != 0)
    71.         JMP JErr
    72.     .ENDIF
    73.  
    74.     ;Шаг 4 - ожидание подключений
    75.    
    76.     INVOKE listen, Sock, SOMAXCONN
    77.     .IF (EAX)
    78.         JMP JErr
    79.     .ENDIF
    80.    
    81.     ;Шаг 5 - извлекаем сообщение из очереди
    82.  
    83.     .REPEAT
    84.         INVOKE accept, Sock, 0, 0
    85.         MOV Client, EAX
    86.         INVOKE CreateThread, 0, 0, addr ClientThread, Client, 0, addr thID
    87.     .UNTIL (!Client)
    88. CreateSocket ENDP
    89.  
    90. END start
    Но после нескольких коннектов\дисконнектов вылетает. Никак не могу найти где ошибка, помогите пожалуйста
     
  2. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    hiho
    У меня (Win32XP SP3) твой текст работает нормально,
    ничего не вылетает на 4-6 клиентах.
    Больше просто лень было )))
    [​IMG]
     
  3. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Win 7 x64, вылетает когда один и тот же клиент переподсоединяется 3-4 раза, причем все функции возвращают то что и должны, просто происходит закрытие приложения, причем даже винда исключение не генерит, проверил, сама программа ExitProcess не вызывает, отсюда и вся проблема. Уж лучше бы ошибки были =)
     
  4. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Ну когда КК эту статью писал 7x64 еще не видать было, так что он не виноват.
    ))
    Как это "один и тот же клиент переподсоединяется"? А как ты тут из-под клиента прервешь сеанс?

    Как вариант - на С собери посмотри отладчиком что кому передается.
     
  5. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    hiho
    Упрости свою ClientThread() до придела и
    как-то продумай наверное ожидание завершения потока, там с WaitForSingleObject() как-то.
     
  6. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Так я и не говорю, что КК виноват, виноват я, вот только где?.. На плюсах собирал - всё нормально. В этой программе всё те же значения возвращает\принимает. Соединение я рву из своей программы-клиента, телнет для соединения не использую. Определил, что программа завершается после того, как из-за разрыва будет выход из потока:

    Код (Text):
    1. ClientThread PROC Sock  : SOCKET
    2.     ....
    3.     INVOKE closesocket, Sock
    4.     ;Этот код выполнится после разрыва
    5. ClientThread ENDP
    Сразу после выхода из потока - вылет. Причем даже вызов Accept-а завершается без ошибок.

    Такое ощущение, что происходит переполнение какой-то переменной(О_о), так как вылетает не после первого подключения.
     
  7. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    разве DWORD может быть меньше 0?
     
  8. yashechka

    yashechka Ростовский фанат Нарвахи

    Публикаций:
    90
    Регистрация:
    2 янв 2012
    Сообщения:
    1.449
    Адрес:
    Россия
    Кто такой крис?
     
  9. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Да есть тут такой сердцеед кудлатый )))
     
  10. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Не доглядел. Исправил, но ошибка осталась

    Крис Касперски. Данная программа написана по его статье http://www.insidepro.com/kk/006/006r.shtml

    PS: Счастливые обладатели Win7 x64, попробуйте погонять код
     
  11. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Ну что, ни один из умных форума сего так и не укажет мне на ошибку?
     
  12. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    На ошибку наверное нет, но направление ))
    У тебя имхо проблема с запущенным процессом. Для начала без CreateThread() собери, посмотри.
     
  13. hiho

    hiho New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2010
    Сообщения:
    6
    Нашел я свою ошибку. Забыл RET при завершении потока, в итоге после выхода из ClientThread он продолжал выполнять код, натыкался на создание сокета и выходил через JMP JErr. Вот код вроде бы рабочего примера:

    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\wsock32.inc
    7. include \masm32\include\user32.inc
    8. include \masm32\include\kernel32.inc
    9. include \masm32\include\shell32.inc
    10.  
    11. includelib \masm32\lib\user32.lib
    12. includelib \masm32\lib\kernel32.lib
    13. includelib \masm32\lib\wsock32.lib
    14. includelib \masm32\lib\shell32.lib
    15.  
    16. CreateSocket PROTO :DWORD
    17. ClientThread PROTO :SOCKET
    18.  
    19. .DATA
    20.     WSA         WSADATA <>
    21.     szOut              db "STOP THREAD",0
    22.     szIn               db "START THREAD",0
    23.     szText             db "ERROR",0
    24.    
    25. .CODE
    26.  
    27. start:
    28.     ; Шаг 1 - Инициализация Библиотеки Сокетов
    29.    
    30.     INVOKE WSAStartup, 202h, addr WSA
    31.     .IF (EAX)
    32.         JMP JErr
    33.     .ENDIF
    34.     INVOKE CreateSocket, 6677
    35.     JErr:
    36.         INVOKE WSACleanup
    37.         INVOKE ExitProcess, 0      
    38.  
    39. CreateSocket PROC Port :DWORD
    40.     LOCAL Sock      : SOCKET
    41.     LOCAL Client    : SOCKET
    42.     LOCAL sin       : sockaddr_in
    43.     LOCAL thID      : DWORD
    44.    
    45.     ; Шаг 2 - создание сокета
    46.    
    47.     INVOKE socket, AF_INET, SOCK_STREAM, 0
    48.     .IF (EAX < 0)
    49.         JMP JErr
    50.     .ENDIF
    51.    
    52.     ;Шаг 3 - связывание сокета с локальным адресом
    53.    
    54.     MOV Sock, EAX                                
    55.     MOV sin.sin_family, AF_INET
    56.     INVOKE htons, Port
    57.     MOV sin.sin_port, AX
    58.     MOV sin.sin_addr, INADDR_ANY
    59.  
    60.     ; Вызываем bind для связывания
    61.    
    62.     INVOKE bind, Sock, addr sin, sizeof sin
    63.     .IF (EAX)
    64.         JMP JErr
    65.     .ENDIF
    66.  
    67.     ;Шаг 4 - ожидание подключений
    68.    
    69.     INVOKE listen, Sock, SOMAXCONN
    70.     .IF (EAX)
    71.         JMP JErr
    72.     .ENDIF
    73.    
    74.     ;Шаг 5 - извлекаем сообщение из очереди
    75.    
    76.     .REPEAT
    77.         INVOKE accept, Sock, 0, 0
    78.         MOV Client, EAX
    79.         INVOKE CreateThread, 0, 0, addr ClientThread, Client, 0, addr thID
    80.     .UNTIL (!Client)
    81. CreateSocket ENDP
    82.  
    83. ClientThread PROC Sock  : SOCKET
    84.     LOCAL Bytes         : DWORD
    85.     LOCAL BufStr[1024]  : BYTE
    86.     LOCAL hThread       : DWORD
    87.     MOV hThread, EAX
    88.     .REPEAT
    89.         INVOKE RtlZeroMemory, addr BufStr, sizeof BufStr
    90.         INVOKE recv, Sock, addr BufStr, sizeof BufStr,0
    91.         MOV Bytes, EAX
    92.         .IF (EAX)
    93.             INVOKE MessageBox, 0, addr BufStr,0,0
    94.         .ENDIF
    95.     .UNTIL (!Bytes)
    96.     INVOKE closesocket, Sock
    97.     INVOKE CloseHandle, hThread
    98.     RET
    99. ClientThread ENDP
    100.  
    101. END start
     
  14. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    hiho
    Пожалуйста ))
     
  15. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    hiho
    Ну и в CreateSocket не помешал бы RET)