<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=186464&amp;view=findpost&amp;p=1580988</guid>
        <pubDate>Mon, 28 May 2007 03:38:27 +0000</pubDate>
        <title>Server/Client Socket</title>
        <link>https://forum.sources.ru/index.php?showtopic=186464&amp;view=findpost&amp;p=1580988</link>
        <description><![CDATA[AndNot:  <br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Асинхронный режим, основанный на событиях</strong></span></span></div><br>
В продолжение темы хотелось бы упомянуть о работе с сокетами с помощью системных объектов событий. Этот режим позволяет эффективнее, чем вышеприведенный, обслуживать большое количество клиентов. Но поскольку я ленивый, то представлю только код сервера, а клиентов можно взять из предыдущей статьи. Данный сервер делает простую задачу, принимает сообщения от клиентов и рассылает их всем подключившимся, что то вроде чата, только примитивного. Собственно код:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">; file: server.asm</div><div class="code_line">&nbsp;&nbsp;.386</div><div class="code_line">&nbsp;&nbsp;.model &nbsp; &nbsp;flat, stdcall</div><div class="code_line">&nbsp;&nbsp;option &nbsp; &nbsp;casemap :none</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\windows.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\user32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\kernel32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\wsock32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\ws2_32.inc</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\wsock32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\ws2_32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\user32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\kernel32.lib</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;WSA_INFINITE &nbsp; &nbsp; &nbsp;equ INFINITE</div><div class="code_line">&nbsp;&nbsp;WSA_WAIT_TIMEOUT &nbsp;equ WAIT_TIMEOUT</div><div class="code_line">&nbsp;&nbsp;WSA_WAIT_FAILED &nbsp; equ WAIT_FAILED</div><div class="code_line">&nbsp;&nbsp;WSA_WAIT_OBJECT_0 equ WAIT_OBJECT_0</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;_T macro p1, p2</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;local l</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ifb &#60;p2&#62;; Строка без имени</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l &nbsp; db p1, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;addr l&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else &nbsp; &nbsp;; Строка с именем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l &nbsp; db p1, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;offset l&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;endm</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DlgProc &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;EditProc &nbsp; &nbsp; &nbsp; &nbsp;proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;MESSG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp;ERROR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD, :BYTE</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 80</div><div class="code_line">&nbsp;&nbsp; &nbsp;VER_SOCKET &nbsp; &nbsp; &nbsp;equ 202h &nbsp; &nbsp; &nbsp; &nbsp;; требуемая версия WinSock</div><div class="code_line">&nbsp;&nbsp; &nbsp;MAX_SOCK &nbsp; &nbsp; &nbsp; &nbsp;equ 16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; максимальное количество обслуживаемых</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; в одном потоке клиентов - 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;BUF_LEN &nbsp; &nbsp; &nbsp; &nbsp; equ 1024 &nbsp; &nbsp; &nbsp; &nbsp;; размер буфера для приема/передачи</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; контролы из ресурсов</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_COUNT &nbsp; &nbsp; &nbsp; equ 101 &nbsp; &nbsp; &nbsp; &nbsp; ; окошко отображения количества клиентов</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_IN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 102 &nbsp; &nbsp; &nbsp; &nbsp; ; приемное &quot;окно&quot; (контрол ListBox)</div><div class="code_line">&nbsp;</div><div class="code_line">.data?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hInstance &nbsp; &nbsp; &nbsp; HINSTANCE ?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hDlg &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HWND ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; хэндл окна диалога</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hSockets &nbsp; &nbsp; &nbsp; &nbsp;dd MAX_SOCK dup(?) &nbsp;; массив хэндлов сокетов</div><div class="code_line">&nbsp;&nbsp; &nbsp;hEvents &nbsp; &nbsp; &nbsp; &nbsp; dd MAX_SOCK dup(?) &nbsp;; массив хэндлов объектов событий</div><div class="code_line">&nbsp;&nbsp; &nbsp;NumSockets &nbsp; &nbsp; &nbsp;dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; количество используемых сокетов</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;NetEvents &nbsp; &nbsp; &nbsp; WSANETWORKEVENTS &#60;&#62; ; это для получения информации о произошедших событиях</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;wsa &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WSADATA &#60;&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; информация о версии WinSock</div><div class="code_line">&nbsp;&nbsp; &nbsp;sin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sockaddr_in &#60;&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; буфер для операций ввода/вывода</div><div class="code_line">&nbsp;&nbsp; &nbsp;IOBuff &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db BUF_LEN+1 dup(?)</div><div class="code_line">&nbsp;</div><div class="code_line">.code</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">start:</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;GetModuleHandle, NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; hInstance, eax</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; инициализируем Windows Sockets DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAStartup, VER_SOCKET, addr wsa</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (eax == NULL) &amp;&amp; (wsa.wVersion == VER_SOCKET)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем диалог</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;DialogBoxParam, hInstance, _T(&quot;MAINDIALOG&quot;), 0, addr DlgProc, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, 0, _T(&quot;Windows socket not found!&quot;), _T(&quot;ERROR&quot;), MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, 90h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; заканчиваем программу с кодом ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;; уходим в хаОС</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;ExitProcess, eax</div><div class="code_line">&nbsp;</div><div class="code_line">; отправляет сообщение сразу всем клиентам</div><div class="code_line">sendall proc buffptr: DWORD, bufflen: DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp;push &nbsp; &nbsp;esi</div><div class="code_line">&nbsp;&nbsp; &nbsp;push &nbsp; &nbsp;ebx</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; esi, offset hSockets+4 &nbsp;; пропускаем слушающий сокет :)</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; ebx, 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;.while (ebx &#60; NumSockets)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;lodsd &nbsp; &nbsp; &nbsp; ; получаем очередной хэндл</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;send, eax, addr IOBuff, BUF_LEN, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; ebx</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endw</div><div class="code_line">&nbsp;&nbsp; &nbsp;pop &nbsp; &nbsp; ebx</div><div class="code_line">&nbsp;&nbsp; &nbsp;pop &nbsp; &nbsp; esi</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">sendall endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; **********************************</div><div class="code_line">; поток по обработке событий сокетов</div><div class="code_line">; **********************************</div><div class="code_line">WorkThread proc Param: DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; NumSockets, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;; создаем сокет для прослушки порта</div><div class="code_line">&nbsp;&nbsp; &nbsp;; обнуляем структуру sockaddr_in</div><div class="code_line">&nbsp;&nbsp; &nbsp;lea &nbsp; &nbsp; edi, sin</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; ecx, sizeof sin</div><div class="code_line">&nbsp;&nbsp; &nbsp;rep &nbsp; &nbsp; stosb</div><div class="code_line">&nbsp;&nbsp; &nbsp;; заполняем структуру sockaddr_in</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;htons, Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; преобразовываем номер порта в сетевой порядок байт</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_port, ax &nbsp; &nbsp; &nbsp; &nbsp;; и сохраняем его</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_family, AF_INET</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;htonl, INADDR_ANY &nbsp; &nbsp; &nbsp; ; принимать с любого адреса</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_addr, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;; создаем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;socket, AF_INET, SOCK_STREAM, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; hSockets, eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; первым элементом массива будет слушающий сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (eax != SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем объект события для данного сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACreateEvent</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hEvents, eax &nbsp; &nbsp; &nbsp; &nbsp;; первым элементом массива будет объект для слушающего сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; связываем его с событиями FD_ACCEPT и FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAEventSelect, hSockets, eax, FD_ACCEPT + FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; NumSockets</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; ассоциируем локальный адрес (Port) с открытым сокетом</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;bind, hSockets, addr sin, sizeof sin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ставим сокет на прослушку порта</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;listen, hSockets, 5 &nbsp;; 5 - размер очереди на входящие запросы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax == SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Can&#39;t listen socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Can&#39;t binding socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Can&#39;t create socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; *********************************************************************</div><div class="code_line">&nbsp;&nbsp; &nbsp;; &quot;вечный&quot; цикл, в котором мы ждем событий от сокетов и обрабатываем их</div><div class="code_line">&nbsp;&nbsp; &nbsp;; *********************************************************************</div><div class="code_line">&nbsp;&nbsp; &nbsp;.while &nbsp;TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; ждем наступления какого либо события на сокетах</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAWaitForMultipleEvents, NumSockets, addr hEvents, FALSE, WSA_INFINITE, FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax == WSA_WAIT_TIMEOUT) || (eax == WSA_WAIT_FAILED) &nbsp; ; проверка на предмет ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Wait for event failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.continue &nbsp; ; ошибочка вышла, будем ждать следующих событий</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ebx, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sub &nbsp; &nbsp; ebx, WSA_WAIT_OBJECT_0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ebx - индекс объекта в массиве hEvents</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; теперь уточняем, какие именно события произошли</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; esi, [hSockets+ebx*4] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; esi - сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [hEvents+ebx*4] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; edx - его объект событий</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; помимо получения инфы о событиях, мы используем функцию и для сброса событий</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAEnumNetworkEvents, esi, edx, addr NetEvents</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edi, NetEvents.lNetworkEvents</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; событий может быть несколько, поэтому проверяем все, и обрабатываем произошедшие</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edi &amp; FD_ACCEPT)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, FD_ACCEPT_BIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; анализируем код ошибки операции</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if ([NetEvents.iErrorCode+eax*4] != 0) ; если ноль, то все Ок!</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Accept failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.continue &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; продолжаем цикл</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; извлекаем из очереди ожидающих подключений первое и</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; создаем новый сокет для связи с клиентом</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;accept, esi, NULL, NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; еще пригодится :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (NumSockets &#62;= MAX_SOCK) &nbsp; &nbsp; &nbsp; &nbsp;; не слишком ли много клиентов?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hDlg, _T(&quot;Too many connections!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, eax &nbsp; &nbsp; &nbsp; &nbsp;; выкидываем нового клиента</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; создаем объект события для нового сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACreateEvent</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; edx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; edx - хэндл созданного сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, NumSockets</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; добавляем хендлы в массив</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [hSockets+ecx*4], edx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [hEvents+ecx*4], eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;ecx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; пригодится для вывода на IDC_COUNT :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; ecx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; NumSockets, ecx &nbsp; &nbsp; &nbsp; &nbsp; ; корректируем счетчик клиентов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; связываем сокет с событиями чтения/записи</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAEventSelect, edx, eax, FD_READ + FD_WRITE + FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hDlg, _T(&quot;new client added!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; обновляем на экране счетчик подключенных клиентов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetDlgItemInt, hDlg, IDC_COUNT, eax, FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; FD_ACCEPT</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edi &amp; FD_READ)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, FD_READ_BIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if ([NetEvents.iErrorCode+eax*4] != 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;read from socket failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, esi &nbsp; &nbsp; &nbsp; &nbsp;; закрываем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.continue &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; продолжаем цикл</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; считываем данные с сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;recv, esi, addr IOBuff, BUF_LEN, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; добавляем сообщение в окно статуса</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hDlg, addr IOBuff</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; и отсылаем всем остальным</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;sendall, addr IOBuff, BUF_LEN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; FD_READ</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edi &amp; FD_WRITE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, FD_WRITE_BIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if ([NetEvents.iErrorCode+eax*4] != 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;write to socket failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, esi &nbsp; &nbsp; &nbsp; &nbsp;; закрываем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.continue &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; продолжаем цикл</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; у нас это событие будет возникать только при создании нового сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; поэтому просто передаем приветствие новому клиенту :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, _T(&quot;Welcom to test server!&quot;, TRUE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;edx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;lstrlen, edx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; edx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;send, esi, edx, eax, 0 &nbsp; &nbsp; &nbsp;; отсылаем приветствие новому клиенту</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; FD_WRITE</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; поскольку в этом событии происходит исключение сокета из массива,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; мы его обрабатываем в последнюю очередь, во избежание лишних проблем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; связанных с перестановками в массивах hSockets и hEvents</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edi &amp; FD_CLOSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, FD_CLOSE_BIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if ([NetEvents.iErrorCode+eax*4] != 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;Close socket failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hDlg, _T(&quot;Close socket!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; нам неважно, была ошибка, или нет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; все равно нужно закрывать сокет и корректировать массивы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [hEvents+ebx*4]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACloseEvent, eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; уничтожаем объект события</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, esi &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; закрываем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; перестраиваем массивы, исключая из них текущий сокет и объект событий</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; esi, [hSockets+ebx*4]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; edi, [hEvents+ebx*4]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, NumSockets</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub &nbsp; &nbsp; ecx, ebx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dec &nbsp; &nbsp; ecx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; ecx - количество элементов для сдвига</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.while &nbsp;(ecx != 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [esi+4]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [edi+4]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [esi], eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; сдвигаем к началу, тем самым исключая</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [edi], edx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; элементы из массивов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; esi, 4</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; edi, 4</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dec &nbsp; &nbsp; ecx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endw</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dec &nbsp; &nbsp; NumSockets &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; корректируем счетчик сокетов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; обновляем на эеране счетчик подключенных клиентов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, NumSockets</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dec &nbsp; &nbsp; eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetDlgItemInt, hDlg, IDC_COUNT, eax, FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endw</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">WorkThread endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; ************************************************</div><div class="code_line">; оконная функция диалога, проста до безобразия :)</div><div class="code_line">; ************************************************</div><div class="code_line">DlgProc proc &nbsp; &nbsp;hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;; определяем пришедшее сообщение</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (uMsg == WM_INITDIALOG)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; меняем заголовок окна диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_SETTEXT, NULL, _T(&quot;Server&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; обновляем на экране счетчик подключенных клиентов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetDlgItemInt, hWnd, IDC_COUNT, 0, FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, hWnd</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hDlg, eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; хэндл окна нам еще понадобится :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; запускаем тред обработки событий сокетов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, esp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; eax - временный буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;CreateThread, NULL, NULL, offset WorkThread, NULL, NULL, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; значение ThreadID нам не нужно</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.elseif (uMsg == WM_CLOSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; подчищаем за собой и выходим</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; выгружаем WinSock DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;EndDialog, hWnd, NULL</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else &nbsp; &nbsp; &nbsp; ; если сообщение не обрабатывали, то вернем NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сообщение обработано, возвращаем ненулевой результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">DlgProc endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;***************************************************************</div><div class="code_line">; функции вывода информационных сообщений и сообщений об ошибках</div><div class="code_line">;***************************************************************</div><div class="code_line">&nbsp;</div><div class="code_line">; просто добавляет строку в ListBox</div><div class="code_line">MESSG proc hWnd: HWND, message: DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItem, hWnd, IDC_IN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, eax, LB_ADDSTRING, 0, message</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; ecx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, ecx, LB_SETTOPINDEX, eax, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">MESSG endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; информирует о последней ошибке, получая ее с помощью WSAGetLastError</div><div class="code_line">; при Fatal &#60;&#62; FALSE сообщение выводится в MessageBox, и программа закрывается.</div><div class="code_line">; при Fatal == FALSE сообщение просто выводится в ListBox</div><div class="code_line">ERROR proc hWnd: HWND, message: DWORD, Fatal: BYTE</div><div class="code_line">&nbsp;&nbsp;local szStr[256]: byte &nbsp; &nbsp;; временный буфер для создания строки</div><div class="code_line">&nbsp;&nbsp; &nbsp;; получаем код последней ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAGetLastError</div><div class="code_line">&nbsp;&nbsp; &nbsp;; формируем строку с сообщением об ошибке</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;wsprintf, addr szStr, _T(&quot;%s Error code: %u&quot;), message, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (Fatal != FALSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, hWnd, addr szStr, _T(&quot;FATAL ERROR&quot;), MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; закрываем диалог, все равно смысла нет в дальнейшей работе :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_CLOSE, 0, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; информируем пользователя, засылая строку в ListBox</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, addr szStr</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">ERROR endp</div><div class="code_line">&nbsp;</div><div class="code_line">end start</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Файл ресурса:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">; file: server.rc</div><div class="code_line">MAINDIALOG DIALOG 22, 46, 190, 93</div><div class="code_line">STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU</div><div class="code_line">CAPTION &quot;Server&quot;</div><div class="code_line">BEGIN</div><div class="code_line">&nbsp;&nbsp;CONTROL 0, 101, &quot;STATIC&quot;, SS_CENTER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP, 154, 21, 28, 12</div><div class="code_line">&nbsp;&nbsp;LTEXT &quot;Clients&quot;, -1, 155, 9, 24, 8, WS_CHILD | WS_VISIBLE | WS_GROUP</div><div class="code_line">&nbsp;&nbsp;LISTBOX 102, 7, 7, 141, 81, LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL</div><div class="code_line">END</div></ol></div></div></div></div><br>
Для сборки программы можно применить следующий bat-файл:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">:: file: makeit.bat</div><div class="code_line">brcc32.exe server.rc</div><div class="code_line">c:\masm32\bin\ml /c /coff /nologo server.asm</div><div class="code_line">c:\masm32\bin\Link /SUBSYSTEM:WINDOWS server.obj server.res</div><div class="code_line">pause</div></ol></div></div></div></div><br>
И в заключение хотелось бы упомянуть о нескольких неочевидных вещах. Дело в том, что <em class='tag-i'>WSAWaitForMultipleEvents</em> может обслуживать не более 64-х объектов событий (константа <em class='tag-i'>WSA_MAXIMUM_WAIT_EVENTS</em>), поэтому, для поддержки большего количества клиентов, создаются дополнительные треды, со своими наборами сокетов и их объектов событий. Что касается применения данной модели к созданию клиентов, то это неплохой вариант для клиента, который может независимо работать с несколькими серверами, достаточно для каждого соединения создать отдельный тред. Ну и, разумеется, в целях наглядности, обработка ошибок сведена к минимуму.]]></description>
        <author>AndNot</author>
        <category>Assembler FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=186464&amp;view=findpost&amp;p=1571660</guid>
        <pubDate>Sat, 19 May 2007 22:17:56 +0000</pubDate>
        <title>Server/Client Socket</title>
        <link>https://forum.sources.ru/index.php?showtopic=186464&amp;view=findpost&amp;p=1571660</link>
        <description><![CDATA[Дьяволица:  <br>
<div class='tag-align-center'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'><strong class='tag-b'>Server/Client Socket</strong></span></span></div><br>
Всем известно, то, что первое появилась это глобальная сеть, а не локальная с приходом протокола <strong class='tag-b'>TCP/IP</strong> для военных целей. Но так как этот способ связи был ненадёжным и опасным для передачи секретных данных, - его начали использовать во всём мире.<br>
<br>
Каждый когда-нибудь хотел написать свой клиент сервер, чтобы пообщаться с другом через Интернет или в локальной сети. Сейчас я покажу и подробно прокомментирую, как это делается средствами <strong class='tag-b'>API – Windows на MASM</strong>(ассемблере).<br>
<br>
<span class='tag-u'>Итак, сервер:</span> главной задачей, которого, является ожидание клиента, обработка пришедшего сообщения, добавление его в <strong class='tag-b'>LISTBOX – controle</strong> и отсылка, что мы написали в <strong class='tag-b'>EDIT – controle</strong>;<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.386</div><div class="code_line">&nbsp;&nbsp;.model &nbsp; &nbsp;flat, stdcall</div><div class="code_line">&nbsp;&nbsp;option &nbsp; &nbsp;casemap :none</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\windows.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\user32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\kernel32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\wsock32.inc</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\wsock32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\user32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\kernel32.lib</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;_T macro p1, p2 ;макрос обработки строк</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;local l</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ifb &#60;p2&#62;; Строка без имени</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l &nbsp; db p1, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;addr l&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else &nbsp; &nbsp;; Строка с именем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p1 &nbsp;db p2, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;addr p1&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;endm</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DlgProc &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;EditProc &nbsp; &nbsp; &nbsp; &nbsp;proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;MESSG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp;ERROR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD, :BYTE</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 80</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_SOCKET &nbsp; &nbsp; &nbsp; equ WM_USER+100</div><div class="code_line">&nbsp;&nbsp; &nbsp;VER_SOCKET &nbsp; &nbsp; &nbsp;equ 101h &nbsp; &nbsp; &nbsp; &nbsp;; требуемая версия WinSock</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BUF_LEN &nbsp; &nbsp; &nbsp; &nbsp; equ 1024 &nbsp; &nbsp; &nbsp; &nbsp;; размер буфера для приема/передачи</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; контролы из ресурсов</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_OUT &nbsp; &nbsp; &nbsp; &nbsp; equ 101 &nbsp; &nbsp; &nbsp; &nbsp; ; строка отсылки (контрол EDIT)</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_IN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 102 &nbsp; &nbsp; &nbsp; &nbsp; ; приемное &quot;окно&quot; (контрол ListBox)</div><div class="code_line">&nbsp;</div><div class="code_line">.data?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hInstance &nbsp; &nbsp; &nbsp; HINSTANCE ?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hDlg &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HWND ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; хэндл окна диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpfnEditProc &nbsp; &nbsp;HWND ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; перехваченная оконная функция EDIT</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hSocket &nbsp; &nbsp; &nbsp; &nbsp; dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; хэндл слушающего сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp;hClient &nbsp; &nbsp; &nbsp; &nbsp; dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; хэндл сокета клиента</div><div class="code_line">&nbsp;&nbsp; &nbsp;IsSend &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; при значении &#62;0 разрешена передача данных клиенту</div><div class="code_line">&nbsp;&nbsp; &nbsp;wsa &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WSADATA &#60;&#62; &nbsp; &nbsp; &nbsp;; информация о версии WinSock</div><div class="code_line">&nbsp;&nbsp; &nbsp;sin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sockaddr_in &#60;&#62; &nbsp;;структура узла</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; буфер для операций ввода/вывода</div><div class="code_line">&nbsp;&nbsp; &nbsp;IOBuff &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db BUF_LEN+1 dup(?)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">.code</div><div class="code_line">&nbsp;</div><div class="code_line">start:</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;GetModuleHandle, NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; hInstance, eax</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; инициализируем Windows Sockets DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAStartup, VER_SOCKET, addr wsa</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (eax == NULL) &amp;&amp; (wsa.wVersion == VER_SOCKET)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем диалог</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;DialogBoxParam, hInstance, _T(&quot;MAINDIALOG&quot;), 0, addr DlgProc, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, 0, _T(&quot;Windows socket not found!&quot;), _T(&quot;ERROR&quot;), \</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, 90h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; заканчиваем программу с кодом ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;; уходим в хаОС</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;ExitProcess, eax</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; оконная функция диалога</div><div class="code_line">DlgProc proc &nbsp; &nbsp;hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;; определяем пришедшее сообщение</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (uMsg == WM_INITDIALOG)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; меняем заголовок окна диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_SETTEXT, NULL, _T(&quot;Server&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; IsSend, FALSE &nbsp; &nbsp; &nbsp; ; запрещаем отправку данных клиенту</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, hWnd</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hDlg, eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; хэндл окна нам еще понадобится :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сабклассируем контрол EDIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItem, eax, IDC_OUT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetWindowLong, eax, GWL_WNDPROC, addr EditProc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; lpfnEditProc, eax &nbsp; ; сохраняем адрес предыдущей функции</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем сокет для прослушки порта на предмет входящих соединений</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;socket, AF_INET, SOCK_STREAM, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hSocket, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; задаем окно для приема сообщений от сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; нам понадобится только FD_ACCEPT и FD_CLOSE(только для SOCK_STREAM)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; автоматически для сокета устанавливается non-block mode.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAAsyncSelect, hSocket, hWnd, WM_SOCKET, FD_ACCEPT+FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; заполням структуру sockaddr_in</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; для начала обнуляем, поскольку заполняем не все поля</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edi, offset sin ;структуру сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, sizeof sin ;размер структуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rep &nbsp; &nbsp; stosb</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; преобразовываем номер порта в сетевой порядок байт</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;htons, Port</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_port, ax &nbsp; &nbsp; &nbsp; &nbsp;; и сохраняем его</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_family, AF_INET ;семейство протоколов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_addr, INADDR_ANY; принимать с любого адреса</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ассоциируем локальный адрес (Port) с открытым сокетом</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;bind, hSocket, addr sin, sizeof sin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ставим сокет на прослушку порта</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;listen, hSocket, 5 &nbsp;; 5 - размер очереди на входящие запросы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax == SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t listen socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t binding socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t select event for socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t create socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.elseif (uMsg == WM_CLOSE) </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; подчищаем за собой и выходим</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, hClient &nbsp; &nbsp;; закрываем сокеты</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, hSocket &nbsp; &nbsp;; если уже закрыты, то ничего страшного :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; выгружаем WinSock DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;EndDialog, hWnd, NULL</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.elseif (uMsg == WM_SOCKET) ;события сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, lParam</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shr &nbsp; &nbsp; edx, 16 &nbsp; &nbsp; &nbsp; &nbsp; ; dx - код ошибки или ноль</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edx != NULL) &nbsp; &nbsp; &nbsp; ; если dx &#60;&#62; NULL то получено извещение о ошибке</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;soket error!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; удаляем сокет вызвавший ошибку</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, wParam</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (ax == FD_ACCEPT)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; извлекаем из очереди ожидающих подключений первое и</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; создаем новый сокет для связи с клиентом</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;accept, wParam, 0, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hClient, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; от него мы будем получать уведомления на чтение/запись/закрытие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAAsyncSelect, eax, hWnd, WM_SOCKET, FD_READ+FD_WRITE+FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;added client socket!&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_CLOSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; закрываем сокет (в wParam его хэндл)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;close socket!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, wParam</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_READ)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; получаем данные с сокета (в wParam его хэндл)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;recv, wParam, addr IOBuff, BUF_LEN, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, addr IOBuff; отправляем их в ListBox</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_WRITE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; извещение о готовности сокета(в wParam его хэндл) к отправке данных</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; IsSend, TRUE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; устанавливам флаг</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;socket is ready for writing!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; WM_SOCKET</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else &nbsp; &nbsp; &nbsp; ; если сообщение не обрабатывали, то вернем NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сообщение обработано, возвращаем ненулевой результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">DlgProc endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; оконная функция контрола EDIT</div><div class="code_line">; просто перехватывает нажатие Enter и отправляет данные клиенту</div><div class="code_line">EditProc proc &nbsp; hCtl: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; eax, wParam</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (uMsg == WM_KEYDOWN) &amp;&amp; (al == VK_RETURN) &amp;&amp; (IsSend != FALSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; нажат Enter, отсылаем строку клиенту</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItemText, hDlg, IDC_OUT, addr IOBuff, BUF_LEN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;send, hClient, addr IOBuff, BUF_LEN, 0</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax==SOCKET_ERROR)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;send failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; очищаем строку ввода</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetDlgItemText, hDlg, IDC_OUT, NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;; нажата любая другая клавиша, вызываем старую функцию контрола</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;CallWindowProc, lpfnEditProc, hCtl, uMsg, wParam, lParam</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">EditProc endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; просто добавляет строку в ListBox</div><div class="code_line">MESSG proc hWnd: HWND, message: DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItem, hWnd, IDC_IN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, eax, LB_ADDSTRING, 0, message</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; ecx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, ecx, LB_SETTOPINDEX, eax, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">MESSG endp</div><div class="code_line">&nbsp;</div><div class="code_line">; информирует о последней ошибке, получая ее с помощью WSAGetLastError</div><div class="code_line">; при Fatal &#60;&#62; FALSE сообщение выводится в MessageBox, и программа закрывается.</div><div class="code_line">; при Fatal == FALSE сообщение просто выводится в ListBox</div><div class="code_line">ERROR proc hWnd: HWND, message: DWORD, Fatal: BYTE</div><div class="code_line">&nbsp;&nbsp;local szStr[256]: byte &nbsp; &nbsp;; временный буфер для создания строки</div><div class="code_line">&nbsp;&nbsp; &nbsp;; получаем код последней ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAGetLastError</div><div class="code_line">&nbsp;&nbsp; &nbsp;; формируем строку с сообщением об ошибке</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;wsprintf, addr szStr, _T(&quot;%s Error code: %u&quot;), message, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (Fatal != FALSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, hWnd, addr szStr, _T(&quot;FATAL ERROR&quot;), MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; закрываем диалог, все равно смысла нет в дальнейшей работе :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_CLOSE, 0, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; информируем пользователя, засылая строку в ListBox</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, addr szStr</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">ERROR endp</div><div class="code_line">&nbsp;</div><div class="code_line">end start</div></ol></div></div></div></div> <strong class='tag-b'>Компилируется:</strong> <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">ml /c /coff Server.ASM</div><div class="code_line">Link /SUBSYSTEM:WINDOWS Server.obj Server.RES</div><div class="code_line">pause</div></ol></div></div></div></div><br>
<span class='tag-u'>Клиент:</span> главной задачей, которого, является подключение к серверу обработка пришедшего сообщения и отсылка, того, что мы написали в <strong class='tag-b'>EDIT – controle</strong>;  <br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;.386</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.model flat, stdcall</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;option casemap :none</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\windows.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\user32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\kernel32.inc</div><div class="code_line">&nbsp;&nbsp;include \masm32\include\wsock32.inc</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\wsock32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\user32.lib</div><div class="code_line">&nbsp;&nbsp;includelib \masm32\lib\kernel32.lib</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;_T macro p1, p2 ;макрос обработки строк</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;local l</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ifb &#60;p2&#62;; Строка без имени</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l &nbsp; db p1, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;addr l&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else &nbsp; &nbsp;; Строка с именем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.data</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p1 &nbsp;db p2, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.code</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exitm &nbsp; &#60;addr p1&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;endm</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DlgProc &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;EditProc &nbsp; &nbsp; &nbsp; &nbsp;proto :HWND, :UINT, :WPARAM, :LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;MESSG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp;ERROR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proto :HWND, :DWORD, :BYTE</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 80</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_SOCKET &nbsp; &nbsp; &nbsp; equ WM_USER+100</div><div class="code_line">&nbsp;&nbsp; &nbsp;VER_SOCKET &nbsp; &nbsp; &nbsp;equ 101h &nbsp; &nbsp; &nbsp; &nbsp;; требуемая версия WinSock</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BUF_LEN &nbsp; &nbsp; &nbsp; &nbsp; equ 1024 &nbsp; &nbsp; &nbsp; &nbsp;; размер буфера для приема/передачи</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; контролы из ресурсов</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_OUT &nbsp; &nbsp; &nbsp; &nbsp; equ 101 &nbsp; &nbsp; &nbsp; &nbsp; ; строка отсылки (контрол EDIT)</div><div class="code_line">&nbsp;&nbsp; &nbsp;IDC_IN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ 102 &nbsp; &nbsp; &nbsp; &nbsp; ; приемное &quot;окно&quot; (контрол ListBox)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">.data?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hInstance &nbsp; &nbsp; &nbsp; HINSTANCE ?</div><div class="code_line">&nbsp;&nbsp; &nbsp;hDlg &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HWND ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; дескриптор окна диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpfnEditProc &nbsp; &nbsp;HWND ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; перехваченная оконная функция EDIT</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hSocket &nbsp; &nbsp; &nbsp; &nbsp; dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; дескриптор сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp;IsSend &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; при значении &#62;0 разрешена передача данных серверу</div><div class="code_line">&nbsp;&nbsp; &nbsp;wsa &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WSADATA &#60;&#62; &nbsp; &nbsp; &nbsp;; информация о версии WinSock</div><div class="code_line">&nbsp;&nbsp; &nbsp;sin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sockaddr_in &#60;&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; буфер для операций ввода/вывода</div><div class="code_line">&nbsp;&nbsp; &nbsp;IOBuff &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db BUF_LEN+1 dup(?)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">.code</div><div class="code_line">&nbsp;</div><div class="code_line">start:</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;GetModuleHandle, NULL ;;получает дескриптор для определенного модуля если </div><div class="code_line">&nbsp;&nbsp; &nbsp; mov &nbsp; &nbsp; hInstance, eax &nbsp; &nbsp; &nbsp; ;файл отображен в пространстве адреса вызова процесса и</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;возвращает дескриптор окна в регистр eax</div><div class="code_line">&nbsp;&nbsp; ; инициализируем Windows Sockets DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAStartup, VER_SOCKET, addr wsa ;версия и структура сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (eax == NULL) &amp;&amp; (wsa.wVersion == VER_SOCKET);если всё ок</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем диалог</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;DialogBoxParam, hInstance, _T(&quot;MAINDIALOG&quot;), 0, addr DlgProc, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup &nbsp;;в обратном случае выгружаем библу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, 0, _T(&quot;Windows socket not found!&quot;), _T(&quot;ERROR&quot;),\ ;окно ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, 90h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; заканчиваем программу с кодом ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;; уходим в хаОС</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;ExitProcess, eax ;выход из процесса </div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; оконная функция диалога</div><div class="code_line">DlgProc proc &nbsp; &nbsp;hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;; определяем пришедшее сообщение окну!</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (uMsg == WM_INITDIALOG)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; меняем заголовок окна диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_SETTEXT, NULL, _T(&quot;Client&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; IsSend, FALSE &nbsp; &nbsp; &nbsp; ; запрещаем отправку данных клиенту</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, hWnd &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;дескриптор окна в регистр еах</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hDlg, eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; дескриптор окна нам еще понадобится :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сабклассируем контрол EDIT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItem, eax, IDC_OUT ;извлекает дескриптор для управления</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetWindowLong, eax, GWL_WNDPROC, addr EditProc ;изменяет атрибут определенного окна. </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; &nbsp;Функция также устанавливает 32-</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; бит величины &nbsp;в определенной компенсации </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;в дополнительную память окна</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; lpfnEditProc, eax &nbsp; ; сохраняем адрес предыдущей функции</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; создаем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;socket, AF_INET, SOCK_STREAM, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; hSocket, eax &nbsp; &nbsp; &nbsp; &nbsp;;запоминаем дескриптор сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR) &nbsp; ; если нет ошибки, то продолжаем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; задаем окно для приема сообщений от сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAAsyncSelect, hSocket, hWnd, WM_SOCKET, \ ;дескриптор сокета, окна; события сокета, &quot;какие события&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_READ+FD_WRITE+FD_CONNECT+FD_CLOSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax != SOCKET_ERROR);если всё ок</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; заполням структуру sockaddr_in</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; для начала обнуляем, поскольку заполняем не все поля</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edi, offset sin ;структуру сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, sizeof sin ;размер структуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rep &nbsp; &nbsp; stosb</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; преобразовываем номер порта в сетевой порядок байт</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;htons, Port</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_port, ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_family, AF_INET ;семейство используемых протоколов для интернет &nbsp;&quot;AF_INET&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; конвертируем строковый формат в IP-адрес</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;inet_addr, _T(&quot;127.0.0.1&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; sin.sin_addr, eax ;загружаем IP в параметр структуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; подключаем созданный сокет к указанному в sin IP- адресу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;connect, hSocket, addr sin, sizeof sin ;дескриптор сокета, адрес и порт удалённого узла и размер структуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax == SOCKET_ERROR) ;ошибка небеда :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; уточняем ошибку :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSAGetLastError</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; если ошибка не равна нижеследующим, то можно продолжать :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (eax != WSAEWOULDBLOCK) &amp;&amp; (eax != WSAEINPROGRESS);ресурс временно недоступен, действие &nbsp;в процессе развития</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t connect!&quot;), TRUE ;ошибки :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t select event for socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;Can&#39;t create socket!&quot;), TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.elseif (uMsg == WM_CLOSE) ;событие закрытия ;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; подчищаем за собой и выходим</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, hSocket; закрываем сокет, если он еще не закрыт</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;WSACleanup &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; выгружаем WinSock DLL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;EndDialog, hWnd, NULL;закрываем диалог</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.elseif (uMsg == WM_SOCKET) ;а вот и узнаём какие события сокета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, lParam &nbsp; &nbsp; &nbsp; &nbsp; ; ax - код события</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shr &nbsp; &nbsp; edx, 16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; dx - код ошибки или ноль</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (edx != NULL) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; если dx &#60;&#62; NULL то получено извещение о ошибке</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hWnd, _T(&quot;soket error!&quot;), FALSE </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; закрываем открытый сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, wParam</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.if (ax == FD_READ) ;событие чтения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; получаем данные с сокета (в wParam его дескриптор)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;recv, wParam, addr IOBuff, BUF_LEN,0 &nbsp;;буфер, размер буфера,флаг</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, addr IOBuff &nbsp; &nbsp;; отправляем их в ListBox, hWnd - дескриптор окна, IOBuff - буфер</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_WRITE) ;событие отправки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; извещение о готовности сокета(в wParam его дескриптор) к отправке данных</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; IsSend, TRUE &nbsp; &nbsp;; выставляем флаг</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;socket is ready for writing!&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_CONNECT) ;событие присоединения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; извещение о успешном соединении с сервером (в wParam дескриптор сокета)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;connected to server!&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.elseif (ax == FD_CLOSE) ;событие закрытия</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; закрываем сокет (в wParam его дескриптор)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, _T(&quot;close server!&quot;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;closesocket, wParam ;закрываем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif &nbsp;; WM_SOCKET</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else &nbsp; &nbsp; &nbsp; ; если сообщение не обрабатывали, то вернем NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; eax, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сообщение обработано, возвращаем ненулевой результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, TRUE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">DlgProc endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; оконная функция контрола EDIT</div><div class="code_line">; просто перехватывает нажатие Enter и отправляет данные серверу</div><div class="code_line">EditProc proc &nbsp; hCtl: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM</div><div class="code_line">&nbsp;&nbsp; &nbsp;mov &nbsp; &nbsp; eax, wParam</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (uMsg == WM_KEYDOWN) &amp;&amp; (al == VK_RETURN) &amp;&amp; (IsSend != FALSE) ;если клавиша энтер и &quot;чистый&quot; флаг</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; отсылаем строку серверу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItemText, hDlg, IDC_OUT, addr IOBuff, BUF_LEN ;дескриптор контрола EDIT его идентификатор, буфер и его размер</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;send, hSocket, addr IOBuff, BUF_LEN, 0 ; дескриптор сокета, буфер его размер и флаг</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.if (eax==SOCKET_ERROR) ;эх ошибка ;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;ERROR, hDlg, _T(&quot;send failed!&quot;), FALSE</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; очищаем строку ввода</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SetDlgItemText, hDlg, IDC_OUT, NULL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;; нажата любая другая клавиша, вызываем старую функцию контрола</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;CallWindowProc, lpfnEditProc, hCtl, uMsg, wParam, lParam</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">EditProc endp</div><div class="code_line">&nbsp;</div><div class="code_line">; просто добавляет строку в ListBox</div><div class="code_line">MESSG proc hWnd: HWND, message: DWORD</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;GetDlgItem, hWnd, IDC_IN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, eax, LB_ADDSTRING, 0, message</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; ecx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, ecx, LB_SETTOPINDEX, eax, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">MESSG endp</div><div class="code_line">&nbsp;</div><div class="code_line">; информирует о последней ошибке, получая ее с помощью WSAGetLastError</div><div class="code_line">; при Fatal &#60;&#62; FALSE сообщение выводится в MessageBox, и программа закрывается.</div><div class="code_line">; при Fatal == FALSE сообщение просто выводится в ListBox</div><div class="code_line">ERROR proc hWnd: HWND, message: DWORD, Fatal: BYTE</div><div class="code_line">&nbsp;&nbsp;local szStr[256]: byte &nbsp; &nbsp;; временный буфер для создания строки</div><div class="code_line">&nbsp;&nbsp; &nbsp;; получаем код последней ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;WSAGetLastError</div><div class="code_line">&nbsp;&nbsp; &nbsp;; формируем строку с сообщением об ошибке</div><div class="code_line">&nbsp;&nbsp; &nbsp;invoke &nbsp;wsprintf, addr szStr, _T(&quot;%s Error code: %u&quot;), message, eax</div><div class="code_line">&nbsp;&nbsp; &nbsp;.if (Fatal != FALSE)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MessageBox, hWnd, addr szStr, _T(&quot;FATAL ERROR&quot;), MB_OK+MB_ICONERROR</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; закрываем диалог, все равно смысла нет в дальнейшей работе :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;SendMessage, hWnd, WM_CLOSE, 0, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;.else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; информируем пользователя, засылая строку в ListBox</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;invoke &nbsp;MESSG, hWnd, addr szStr</div><div class="code_line">&nbsp;&nbsp; &nbsp;.endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;ret</div><div class="code_line">ERROR endp</div><div class="code_line">&nbsp;</div><div class="code_line">end start</div></ol></div></div></div></div><strong class='tag-b'>Компилируется: </strong><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">ml /c /coff Client.ASM</div><div class="code_line">Link /SUBSYSTEM:WINDOWS Client.obj Client.RES</div><div class="code_line">pause</div></ol></div></div></div></div> <br>
<br>
<span class='tag-u'>Ресурс диалога для «общения» с пользователем:</span><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">MAINDIALOG DIALOG 17, 30, 160, 82</div><div class="code_line">STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU</div><div class="code_line">CAPTION &quot;MAINDIALOG&quot;</div><div class="code_line">BEGIN</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;CONTROL &quot;&quot;, 101, &quot;EDIT&quot;, ES_LEFT | ES_MULTILINE | WS_CHILD | WS_VISIBLE | \</div><div class="code_line">WS_BORDER | WS_TABSTOP, 8, 64, 144, 12</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;LISTBOX 102, 7, 7, 145, 49, LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER |\</div><div class="code_line">&nbsp;WS_VSCROLL</div><div class="code_line">END</div></ol></div></div></div></div> Компилируется борландским компилятором ресурсов brcc32 <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">brcc32.exe -32 Client/Server.txt</div><div class="code_line">pause</div></ol></div></div></div></div><br>
В некоторых местах не была вставлена функция обработки ошибок, только в самых необходимых. Это только пример, и в реальных прогах такое не приветствуется ;) Насчет recv и send. Данные функции не гарантируют передачу/прием блока данных за один раз. В данном примере это несущественно. Этот пример относится к WSAAsyncSelect Model. Есть также Select model, WSAEventSelect Model, и Overlapped Model(пожалуй самая интересная ;) ).]]></description>
        <author>Дьяволица</author>
        <category>Assembler FAQ</category>
      </item>
	
      </channel>
      </rss>
	