Список кодов ошибок, которые возникают при вызове команды send: Код ошибкиhexОписаниеWSANOTINITIALISED276DПеред использованием функции необходимо вызвать функцию WSAStartupWSAENETDOWN2742Сбой в сетиWSAEACCES271DУказанный адрес является широковещательным (broadcast), однако перед вызовом функции не был установлен соответствующий флагWSAEINTR2714Работа функции была отменена при помощи функции WSACancelBlockingCallWSAEINPROGRESS2734Выполняется блокирующая функция интерфейса Windows SocketsWSAEFAULT271EПараметр buf указан неправильно (он не указывает на адресное пространство, принадлежащее приложению)WSAENETRESET2744Необходимо сбросить соединениеWSAENOBUFS2747Возникла блокировка буфераWSAENOTCONN2749Сокет не подсоединенWSAENOTSOCK2736Указанный в параметре дескриптор не является сокетомWSAESHUTDOWN274AСокет был закрыт функцией shutdownWSAEWOULDBLOCK2733Сокет отмечен как неблокирующий, но запрошенная операция приведет к блокировкеWSAEMSGSIZE2738Был использован сокет типа SOCK_DGRAM (предназначенный для передачи датаграмм). При этом размер пакета данных превышает максимально допустимый для данной реализации интерфейса Windows SocketsWSAEINVAL2726Сокет не был подключен функцией bindWSAECONNABORTED2745Сбой из-за слишком большой задержки или по другой причинеWSAECONNRESET2746Сброс соединения удаленным узломПри выполнении функции recv могут возникать следующие ошибки: Код ошибкиhexОписаниеWSANOTINITIALISED276DПеред использованием функции необходимо вызвать функцию WSAStartupWSAENETDOWN2742Сбой в сетиWSAENOTCONN2749Сокет не подсоединенWSAEINTR2714Работа функции была отменена при помощи функции WSACancelBlockingCallWSAEINPROGRESS2734Выполняется блокирующая функция интерфейса Windows SocketsWSAENOTSOCK2736Указанный в параметре дескриптор не является сокетомWSAESHUTDOWN274AСокет был закрыт функцией shutdownWSAEWOULDBLOCK2733Сокет отмечен как неблокирующий, но запрошенная операция приведет к блокировкеWSAEMSGSIZE2738Размер пакета данных превышает размер буфера, в результате чего принятый пакет был обрезанWSAEINVAL2726Сокет не был подключен функцией bindWSAECONNABORTED2745Сбой из-за слишком большой задержки или по другой причинеWSAECONNRESET2746Сброс соединения удаленным узломПередача и прием данных в цикле может привести к блокировке работы приложения. Если это неприемлемо, следует воспользоваться асинхронным расширением интерфейса Windows Sockets. Приложение демонстрирует асинхронный прием данных. После установки канала связи оно вызывает функцию WSAAsyncSelect, указывая в качестве последнего параметра комбинацию констант FD_READ и FD_CLOSE. Функция главного окна приложения получает сообщение WSA_NETEVENT в тот момент времени, когда чтение данных не вызовет блокировки приложения: Код (C): #define WSA_NETEVENT (WM_USER + 2) rc = WSAAsyncSelect (srv_socket, hWnd, WSA_NETEVENT, FD_READ | FD_CLOSE); При необходимости выполнения асинхронной посылки данных нужно указать функцию WSAAsyncSelect и параметр FD_WRITE. Если функция WSAAsyncSelect выполнилась успешно ― возвращается нулевое значение, при ошибке ― значение SOCKET_ERROR. В зависимости от значения последнего параметра могут возникать разные коды ошибки, которые можно получить при помощи функции WSAGetLastError. Следующие ошибки могут возникнуть при любом значении параметра: Код ошибкиhexОписаниеWSANOTINITIALISED276DПеред использованием функции необходимо вызвать функцию WSAStartupWSAENETDOWN2742Сбой в сетиWSAEINVAL2726Сокет не был подключен функцией bindWSAEINPROGRESS2734Выполняется блокирующая функция интерфейса Windows SocketsДополнительный код ошибки можно получить из параметра lParam при помощи макрокоманды WSAGETSELECTERROR. При использовании параметра FD_CONNECT возможно появление следующих ошибок: Код ошибкиhexОписаниеWSAEADDRINUSE2740Указанный адрес уже используетсяWSAEADDRNOTAVAIL2741Указанный адрес не доступенWSAEAFNOSUPPORT273FДля данного сокета нельзя использовать указанное семейство адресовWSAECONNREFUSED274DПопытка установления канала связи была отвергнутаWSAEDESTADDRREQ2737Необходимо указать адрес получателя пакетаWSAEFAULT271EНеправильно указан параметр namelenWSAEINVAL2726Сокет уже подключен к адресуWSAEISCONN2748Сокет уже подсоединенWSAEMFILE2728Больше нет доступных дескрипторовWSAENETUNREACH2743Из данного узла и в данное время невозможно получить доступ к сетиWSAENOBUFS2747Нет места для размещения буфераWSAENOTCONN2749Сокет на подключенWSAENOTSOCK2736Указан дескриптор файла, а не сокетаWSAETIMEDOUT274CПри попытке установления канала связи возникла задержка во времениЕсли используется параметр FD_CLOSE, может возникнуть одна из следующих ошибок: Код ошибкиhexОписаниеWSAENETDOWN2742Сбой в сетиWSAECONNRESET2746Сброс соединения удаленным узломWSAECONNABORTED2745Сбой из-за слишком большой задержки или по другой причинеВ том случае, когда указаны параметры FD_READ, FD_WRITE, FD_OOB, или FD_ACCEPT, может возникнуть ошибка с кодом WSAENETDOWN. Обработчик сообщения WSA_NETEVENT должен выполнить анализ причины, по которой он был вызван, так как за один вызов функции WSAAsyncSelect можно задать несколько событий, вызывающих генерацию сообщения. Этот анализ проводится следующим образом: Код (C): void WndProc_OnWSANetEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { char szTemp[256]; int rc; // Если на сокете выполняется передача данных, // прием и отображение этих данных в виде текстовой строки if(WSAGETSELECTEVENT(lParam) == FD_READ ) { rc = recv ((SOCKET)wParam, szTemp, 256, 0); if(rc) { szTemp[rc] = '\0'; MessageBox(NULL, szTemp, "Reсeived data", MB_OK); } return; } // Если соединение завершено -- вывод сообщения else if(WSAGETSELECTEVENT(lParam) == FD_CLOSE ) { MessageBox(NULL, "Connection closed", "Server", MB_OK); } } Параметр wParam содержит дескриптор сокета, на котором выполняется передача данных, параметр lParam ― код события, которое произошло в сети. Текст приложения-сервера (12s.asm) Код (ASM): ; GUI # include win64a.inc ID_TXT equ 100 ID_SEND_TXT equ 101 ID_SEND_ICO equ 102 ID_SEND_WAV equ 103 IDC_DIALOG equ 200 IDC_ICON1 equ 500 IDC_IMG1 equ 104 WINSOCK_VERSION equ 504 SD_RECEIVE equ 0 SD_SEND equ 1 SD_BOTH equ 2 WSADATA struct wVersion dw ?; wHighVersion dw ? szDescription db (WSADESCRIPTION_LEN + 1) dup(?) szSystemStatus db (WSASYS_STATUS_LEN + 1) dup(?) iMaxSockets dw ? iMaxUdpDg dw ? lpVendorInfo dq ? WSADATA ends S_UN_B STRUCT s_b1 BYTE ? s_b2 BYTE ? s_b3 BYTE ? s_b4 BYTE ? S_UN_B ENDS S_UN_W STRUCT s_w1 WORD ? s_w2 WORD ? S_UN_W ENDS ADDRESS_UNION UNION S_un_b S_UN_B <> S_un_w S_UN_W <> S_addr DWORD ? ADDRESS_UNION ENDS in_addr STRUCT S_un ADDRESS_UNION <> in_addr ENDS SOCKADDR_IN STRUCT sin_family dw ?;is the same as af parameter in socket call. You must use AF_INET here. sin_port dw ?;is the port that the socket will use to communicate with the remote socket. ;This value depends on the higher level protocol that you want to use. If you want to connect to ;the remote socket for HTTP, use port 80 (decimal). However, note that the port value MUST be in ;network byte order that is big Endian. So you cannot use the port value per se but you must call ;htons to convert the value to network byte order first. This is one of the most common error the ;newcomers to winsock programming encounter. sin_addr in_addr <>;is the IP address of the remote host. Again, you must convert the ;IP address to network byte order before using it sin_zero BYTE 8 dup(?);is reserved. Don't mess with it SOCKADDR_IN ends .code WinMain proc enter 30h,0 mov r9d,256;cx mov [rbp-10h],r9 mov qword ptr [rbp-8],LR_DEFAULTCOLOR invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR mov r9d,offset DialogProc mov qword ptr[rbp-10h],rax;30h-10h=+20h invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP invoke RtlExitUserProcess,NULL WinMain endp DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local hFile:qword local cbWritten:dword local hResource:qword local pResource:qword local wsa:WSADATA local port:qword local FSize:qword mov hWnddlg,rcx mov lParam,r9 cmp edx,WM_INITDIALOG je wmINITDIALOG cmp edx,WM_CLOSE je wmCLOSE cmp edx,WM_COMMAND je wmCOMMAND cmp edx,WM_DESTROY je wmDESTROY xor eax,eax jmp exit0 wmDESTROY:invoke WSACleanup jmp wmBYE wmSEND_WAV:mov port,12345 mov type0,WM_USER+3 mov ecx,offset wav_file xor r9d,r9d mov qword ptr[rsp+30h],r9 mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE mov qword ptr[rsp+20h],OPEN_EXISTING invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\ FILE_SHARE_READ or FILE_SHARE_WRITE mov hFile,rax invoke GetFileSize,eax,0 mov FSize,rax invoke GlobalAlloc,GPTR,eax mov p,rax lea r9d,cbWritten and qword ptr[rsp+20h],0 invoke ReadFile,hFile,eax,FSize invoke CloseHandle,hFile jmp @f wmSEND_ICO:mov port,12344 mov type0,WM_USER+2 mov edx,p1 invoke FindResource,0,,RT_ICON; find the resource mov hResource,rax invoke SizeofResource,0,eax ; get its size mov FSize,rax invoke LoadResource,0,hResource ; load the resource invoke LockResource,eax;pResource mov p,rax and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0 mov qword ptr[rsp+20h],256 mov qword ptr[rsp+28h],256 invoke CreateIconFromResourceEx,eax,FSize,TRUE,30000h;270376,TRUE,30000h mov [rsp+20h],rax invoke SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON xor p1,11b jmp @f wmSEND_TXT:mov port,12343 mov type0,WM_USER+1 invoke GlobalAlloc,GPTR,256 mov p,rax invoke GetDlgItemText,hWnddlg,ID_TXT,eax,256 inc eax mov FSize,rax @@: mov edx,offset szWin invoke FindWindow,NULL or eax,eax jz wmBYE ; Отправить данные получателю invoke PostMessage,eax,type0,hWnddlg,FSize invoke SendData,p,FSize,port jmp wmBYE wmINITDIALOG:invoke GetDlgItem,,IDC_IMG1 invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam ; активировать библиотеку сокетов lea edx,wsa invoke WSAStartup,WINSOCK_VERSION ;An error occured if eax != null, because there's no return value for this api, if there's return, ;there's an error jmp wmBYE wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT je wmSEND_TXT cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV je wmSEND_WAV cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO je wmSEND_ICO cmp r8d,BN_CLICKED shl 16 + IDCANCEL jne wmBYE wmCLOSE:invoke EndDialog,,0 wmBYE: mov eax,TRUE exit0: leave retn DialogProc endp SendData proc buf:qword,len:qword,port:qword local sock:QWORD local saddr:SOCKADDR_IN;sizeof(saddr)) =10h local bytesSent:dword mov buf,rcx mov len,rdx mov port,r8 ; создать сокет invoke socket,AF_INET, SOCK_STREAM, IPPROTO_TCP mov sock,rax cmp eax,INVALID_SOCKET jz exit0;if (sock != INVALID_SOCKET) mov saddr.sin_family,AF_INET invoke htonl,INADDR_LOOPBACK mov saddr.sin_addr.S_un.S_addr,eax invoke htons,port;12345 mov saddr.sin_port,ax ;After the socket is created, you have two choices: wait for an incoming connection or connect ;to a remote socket. If you want to wait for incoming connection, you must call listen to listen ;for an incoming connection and call accept to establish connection with the remote socket. If you ;want to connect to a remote socket, you must call connect mov r8d,sizeof saddr;the size of SOCKADDR_IN structure lea edx,saddr;a pointer to a SOCKADDR_IN structure invoke connect,sock;socket descriptor of the local socket. You can pass the socket ;descriptor returned by socket call as this parameter or eax,eax jnz @0;if (connect (sock,(struct sockaddr*)&saddr,sizeof (saddr)) == 0) @@: cmp len,0 ; while (size) jz @0 ;use send to send data on a stream socket and sendto to send data on a datagram socket. I'll ;examine send here since many popular protocols such as HTTP and FTP use stream sockets. ; запрос пришел - посылаем информацию invoke send,sock,buf,len, 0 ;Parameters ; #1 socket == socket descriptor ; #2 buffer == address of the data that you want to send. The data need not be NULL-terminated ;since its size is specified in len parameter. ; #3 len == the size of data to send ; #4 flags == flags specifying the behavior of the function. There are two flags you can use: ; MSG_DONTROUTE : specifies that the data should not be subject to routing. Notice ;the word "should". Some windows socket implementation may ignore this flag. ; MSG_OOB : specifies that the data is out-of-band data. ;Normally we don't use any of these two flags, flags parameter should be 0 in this case. ;If the call is unsuccessful, the value SOCKET_ERROR is returned in eax. ;If it's successful, the actual number of bytes sent is returned in eax. Note that this number ;may not be equal to len parameter. or eax,eax jz @0;if (bytesSent <= 0) break; sub len,rax; size -= (uint32_t)bytesSent; add buf,rax; data = (uint8_t*)data + bytesSent; jmp @b ; закрыть связь @0: invoke shutdown,sock,SD_BOTH ; закрыть сокет invoke closesocket,sock exit0: leave ret SendData endp ;--------------------------------------- .data szWin db 'Socket Reciever',0 wav_file db '..\Images\03.wav',0 p dq ? p1 dd 1 type0 dq ? end rc-файл (12s.rc) Код (C): #include "resource.h" #define ID_TXT 100 #define ID_SEND_TXT 101 #define ID_SEND_ICO 102 #define ID_SEND_WAV 103 #define IDC_IMG1 104 #define IDC_DIALOG 200 #define IDC_ICON1 500 IDC_ICON1 ICON "..\\Images\\icon1.ico" IDC_ICON2 ICON "..\\Images\\icon2.ico" IDC_DIALOG DIALOG 0, 0, 212, 140 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK CAPTION "Socket Sender" BEGIN CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24 CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW | WS_VISIBLE | SS_ICON,5,23,128,128 CONTROL "Write something and click 'Send Text'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13 DEFPUSHBUTTON "Send Text",ID_SEND_TXT,149,27,60,15 PUSHBUTTON "Send ICO", ID_SEND_ICO,149,45,60,15 PUSHBUTTON "Send WAV", ID_SEND_WAV,149,65,60,15 PUSHBUTTON "Exit", IDCANCEL, 149,85,60,15 END Текст приложения-клиента (12r.asm) Код (ASM): ; GUI # include win64a.inc IDC_DIALOG equ 200 IDC_OUTPUT equ 100 ID_ICON equ 102 IDC_ICON1 equ 500 WINSOCK_VERSION equ 504 SD_RECEIVE equ 0 SD_SEND equ 1 SD_BOTH equ 2 WSADATA struct wVersion dw ?; wHighVersion dw ? szDescription db (WSADESCRIPTION_LEN + 1) dup(?) szSystemStatus db (WSASYS_STATUS_LEN + 1) dup(?) iMaxSockets dw ? iMaxUdpDg dw ? lpVendorInfo dq ? WSADATA ends S_UN_B STRUCT s_b1 BYTE ? s_b2 BYTE ? s_b3 BYTE ? s_b4 BYTE ? S_UN_B ENDS S_UN_W STRUCT s_w1 WORD ? s_w2 WORD ? S_UN_W ENDS ADDRESS_UNION UNION S_un_b S_UN_B <> S_un_w S_UN_W <> S_addr DWORD ? ADDRESS_UNION ENDS in_addr STRUCT S_un ADDRESS_UNION <> in_addr ENDS SOCKADDR_IN STRUCT sin_family WORD ? sin_port WORD ? sin_addr in_addr <> sin_zero BYTE 8 dup (?) SOCKADDR_IN ends .code WinMain proc enter 30h,0 mov r9d,offset DialogProc and qword ptr[rbp-10h],0 invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP invoke RtlExitUserProcess,NULL WinMain endp DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword local wsa:WSADATA local clientSocket:qword local saddr:SOCKADDR_IN;sizeof(saddr)=10h local addrSize:dword local buffer[1024]:byte local lpwiocb:WAVEHDR local hWaveOut:qword mov hWnddlg,rcx mov lParam,r9 cmp edx,WM_INITDIALOG je wmINITDIALOG cmp edx,WM_CLOSE je wmCLOSE cmp edx,WM_COMMAND je wmCOMMAND cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_USER+1 je wmUSER_1 cmp edx,WM_USER+2 je wmUSER_2 cmp edx,WM_USER+3 je wmUSER_3 xor eax,eax jmp exit0 wmDESTROY:cmp serverSocket,INVALID_SOCKET jz wmBYE invoke shutdown,serverSocket,SD_BOTH invoke closesocket,serverSocket or serverSocket,INVALID_SOCKET jmp wmBYE wmUSER_1:cmp serverSocket,INVALID_SOCKET jz @f invoke shutdown,serverSocket,SD_BOTH invoke closesocket,serverSocket ; Create a stream socket for internet use ; создать сокет @@: invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP mov serverSocket,rax cmp eax,INVALID_SOCKET jz break ; подключить сокет mov saddr.sin_family,AF_INET invoke htonl,INADDR_LOOPBACK mov saddr.sin_addr.S_un.S_addr,eax invoke htons,12343; convert port number into network byte order first mov saddr.sin_port,ax; адрес порта mov r8d,sizeof saddr lea edx,saddr invoke bind,serverSocket or eax,eax;if (bind (serverSocket, (struct sockaddr*)&saddr, sizeof(saddr)) == 0) jnz break ; перевести сокет в состояние "слушать" invoke listen,serverSocket,256 or eax,eax jnz break;if (listen (serverSocket, 256) == 0) ; ждем запроса от клиента mov addrSize,sizeof saddr lea edx,saddr lea r8d,addrSize invoke accept,serverSocket mov clientSocket,rax cmp eax,INVALID_SOCKET jz break;if (clientSocket == INVALID_SOCKET) break; ; запрос пришел - посылаем информацию @@: lea edx,buffer invoke recv,clientSocket,,1024,0 ;recv is for use with a stream socket ;Parameters: ; #1 socket == socket descriptor ; #2 buffer == address of the memory block to store the incoming data. ; #3 len == the size of the memory block ; #4 flags == flags specifying the behavior of the function. There are two flags you can use: ; MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not ;removed from the input queue. ; MSG_OOB Process out-of-band data. This flag is usually used when FD_OOB notification ;is received. If the call is successful, it returns the number of bytes read from the socket. If it ;is unsuccessful, the value SOCKET_ERROR is returned. If the return value is 0, the remote socket ;has been closed or eax,eax jnz @b;if (len <= 0) break ; выводим строку символов lea r8d,buffer invoke SetDlgItemText,hWnddlg,IDC_OUTPUT jmp @0 wmUSER_2:;mov rax,lParam mov FSize,r9;ax cmp serverSocket,INVALID_SOCKET jz @f invoke shutdown,serverSocket,SD_BOTH invoke closesocket,serverSocket @@: invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP; Create a stream socket for internet use mov serverSocket,rax cmp serverSocket,INVALID_SOCKET jz break mov saddr.sin_family,AF_INET invoke htonl,INADDR_LOOPBACK mov saddr.sin_addr.S_un.S_addr,eax invoke htons,12344; convert port number into network byte order first mov saddr.sin_port,ax mov r8d,sizeof saddr lea edx,saddr invoke bind,serverSocket or eax,eax;if (bind (serverSocket, (struct sockaddr*)&saddr, sizeof(saddr)) == 0) jnz break invoke listen,serverSocket,256 or eax,eax jnz break;if (listen (serverSocket, 256) == 0) mov addrSize,sizeof saddr lea edx,saddr lea r8d,addrSize invoke accept,serverSocket mov clientSocket,rax cmp eax,INVALID_SOCKET jz break;if (clientSocket == INVALID_SOCKET) break; invoke GlobalAlloc,GPTR,FSize mov p,rax mov edi,eax @@: lea edx,buffer invoke recv,clientSocket,,1024,0 or eax,eax jz @f lea esi,buffer mov ecx,eax;1024 rep movsb jmp @b;if (len <= 0) break; @@: invoke CreateIconFromResourceEx,p,FSize,TRUE,30000h,256,256,LR_DEFAULTCOLOR invoke SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON,eax jmp @1 wmUSER_3:;mov rax,lParam mov FSize,r9;ax cmp serverSocket,INVALID_SOCKET jz @f invoke shutdown,serverSocket,SD_BOTH invoke closesocket,serverSocket @@: invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP; Create a stream socket for internet use mov serverSocket,rax cmp eax,INVALID_SOCKET jz break mov saddr.sin_family,AF_INET invoke htonl,INADDR_LOOPBACK mov saddr.sin_addr.S_un.S_addr,eax invoke htons,12345; convert port number into network byte order first mov saddr.sin_port,ax mov r8d,sizeof saddr lea edx,saddr invoke bind,serverSocket or eax,eax;if (bind (serverSocket, (struct sockaddr*)&saddr, sizeof(saddr)) == 0) jnz break invoke listen,serverSocket,256 or eax,eax jnz break;if (listen (serverSocket, 256) == 0) mov addrSize,sizeof saddr lea edx,saddr lea r8d,addrSize invoke accept,serverSocket mov clientSocket,rax cmp eax,INVALID_SOCKET jz break;if (clientSocket == INVALID_SOCKET) break; invoke GlobalAlloc,GPTR,FSize mov p,rax mov edi,eax @@: lea edx,buffer invoke recv,clientSocket,,1024,0 or eax,eax jz @f lea esi,buffer mov ecx,eax;1024 rep movsb jmp @b;if (len <= 0) break; @@: mov r8,p ;"RIFF"+(File size)+(File Type Header)+(Format chunk marker)+(Length of format data) = 14h add r8d,14h invoke waveOutOpen,&hWaveOut,WAVE_MAPPER,,0,0,WAVE_ALLOWSYNC ; Подготавливаем заголовок для вывода lea edx,lpwiocb mov edi,edx xor eax,eax mov ecx,(sizeof WAVEHDR)/8 rep stosq mov rax,p ;"RIFF"+(File size)+(File Type Header)+(Format chunk marker)+(Length of format data)+\ ;(Type of format)+(Number of Channels)+(Sample Rate)+(Sample Rate*BitsPerSample*Channels/8)+\ ;(BitsPerSample*Channels/8)+(Bits per sample)+(“data” chunk header)+(Size of the data section)=2Ch add rax,2Ch mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных mov rax,FSize sub eax,2Ch mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR ; Запускаем проигрывание блока invoke waveOutWrite,hWaveOut,&lpwiocb,sizeof WAVEHDR @@: test lpwiocb.dwFlags,WHDR_DONE jz @b invoke waveOutUnprepareHeader,hWaveOut,&lpwiocb,sizeof WAVEHDR invoke waveOutClose,hWaveOut ;---------------------------------------------------------- @1: invoke GlobalFree,p ; закрыть связь @0: invoke shutdown,clientSocket,SD_BOTH ; закрыть сокет invoke closesocket,clientSocket ;This function closes a socket. Every resource of the socket will be released break: cmp serverSocket,INVALID_SOCKET;if (serverSocket != INVALID_SOCKET) jz wmBYE invoke shutdown,serverSocket,SD_BOTH invoke closesocket,serverSocket mov serverSocket,INVALID_SOCKET jmp wmBYE wmINITDIALOG:;mov hWnd,rcx ; Найти окно отправителя mov edx,offset szWin invoke FindWindow,NULL or eax,eax jnz wmBYE mov edx,offset Error1 mov r8d,offset szAppName invoke MessageBox,hWnddlg,,,MB_ICONEXCLAMATION or MB_YESNO cmp eax,IDNO jz wmBYE mov ecx,offset szService invoke WinExec,,SW_SHOW ;активировать библиотеку сокетов lea edx,wsa invoke WSAStartup,WINSOCK_VERSION jmp wmBYE ;-------------------------------------------------- wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL jne wmBYE wmCLOSE:invoke EndDialog,,0 wmBYE: mov eax,TRUE exit0: leave retn DialogProc endp ;----------------------------------------------------------------------- .data szWin db "Socket Sender",0 Error1 db "The server is not running.",10,"Run?",0 szAppName db "Socket Reciever",0 szService db "12s",0 serverSocket dq INVALID_SOCKET ;threadHandleTxt dq ? ;threadHandleIco dq ? ;threadHandleWav dq ? ;threadId dd ? ;hWnd dq ? FSize dq ? p dq ? end rc-файл (08r.rc) Код (C): #include "resource.h" #define IDC_DIALOG 200 #define IDC_OUTPUT 100 #define ID_ICON 102 IDC_DIALOG DIALOG 0,0,212,140 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK CAPTION "Socket Reciever" BEGIN CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24 CONTROL "",IDC_OUTPUT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13 DEFPUSHBUTTON "Exit",IDCANCEL,149,27,60,15 CONTROL 1,ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128 END в аттаче ASM-/RC-/EXE-файлы Благодарности Огромное спасибо rmn за подсказки, замечания и предоставленную программу
09_MutexБлин #2. Более удачный, хотя и не последний вариант Пока только текст, но выводится без ошибок, вариант с передачей картинок и WAV-файлов будет позже (хотя есть вероятность, что механизм мьютексов не предназначен для такого интенсивного обмена сообщениями, но буду пробовать )...