WIN32汇编语言教程:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(2)
.data?
hWinMain dd ?
hSocket dd ?
szReadBuffer db 32768 dup (?)
.const
szIP db '127.0.0.1',0
szErrIP db '无效的服务器IP地址!',0
dwReturn dd -1
;####################################################################
; 代码段
;####################################################################
.code
;####################################################################
; 接收到UDP数据包时显示到edit控件中,然后回复一个 -1
;####################################################################
_RecvData proc _hSocket
local @dwRecv,@dwSize
local @stSin:sockaddr_in
mov @dwSize,sizeof @stSin
invoke RtlZeroMemory,addr szReadBuffer,sizeof szReadBuffer
invoke RtlZeroMemory,addr @stSin,sizeof @stSin
invoke recvfrom,_hSocket,addr szReadBuffer,\
sizeof szReadBuffer,\
0,addr @stSin,addr @dwSize
.if eax != SOCKET_ERROR
invoke sendto,hSocket,addr dwReturn,4,\
0,addr @stSin,sizeof sockaddr_in
.if eax == SOCKET_ERROR
invoke WSAGetLastError
.if eax == WSAEWOULDBLOCK
invoke GetDlgItem,hWinMain,IDOK
invoke EnableWindow,eax,FALSE
.endif
.endif
invoke GetDlgItem,hWinMain,IDC_INFO
mov ebx,eax
invoke GetWindowTextLength,ebx
invoke SendMessage,ebx,EM_SETSEL,eax,eax
invoke SendMessage,ebx,EM_REPLACESEL,\
FALSE,addr szReadBuffer
.endif
ret
_RecvData endp
;####################################################################
; 将输入框中的文字发送出去
;####################################################################
_SendData proc
local @szBuffer[1024]:byte
local @stSin:sockaddr_in
invoke RtlZeroMemory,addr @stSin,sizeof @stSin
invoke GetDlgItemText,hWinMain,IDC_SERVER,\
addr @szBuffer,sizeof @szBuffer
invoke inet_addr,addr @szBuffer
.if eax == INADDR_NONE
invoke MessageBox,hWinMain,addr szErrIP,NULL,\
MB_OK or MB_ICONWARNING
jmp @F
.endif
mov @stSin.sin_addr,eax
mov @stSin.sin_family,AF_INET
invoke htons,UDP_PORT
mov @stSin.sin_port,ax
invoke GetDlgItemText,hWinMain,IDC_TEXT,\
addr @szBuffer,sizeof @szBuffer
invoke lstrlen,addr @szBuffer
.if eax
mov ecx,eax
invoke sendto,hSocket,addr @szBuffer,ecx,\
0,addr @stSin,sizeof sockaddr_in
.if eax == SOCKET_ERROR
invoke WSAGetLastError
.if eax == WSAEWOULDBLOCK
invoke GetDlgItem,hWinMain,IDOK
invoke EnableWindow,eax,FALSE
.endif
.endif
.endif
@@:
invoke SetDlgItemText,hWinMain,IDC_TEXT,NULL
ret
_SendData endp
;####################################################################
; 初始化 Socket
;####################################################################
_Init proc
local @stWsa:WSADATA
invoke SetDlgItemText,hWinMain,IDC_SERVER,addr szIP
invoke WSAStartup,101h,addr @stWsa
invoke socket,AF_INET,SOCK_DGRAM,0
mov hSocket,eax
invoke WSAAsyncSelect,hSocket,hWinMain,WM_SOCKET,\
FD_READ or FD_WRITE
ret
_Init endp
;####################################################################
; 主窗口程序
;####################################################################
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
;********************************************************************
.if eax == WM_SOCKET
mov eax,lParam
.if ax == FD_READ
invoke _RecvData,wParam
.elseif ax == FD_WRITE
invoke GetDlgItem,hWnd,IDOK
invoke EnableWindow,eax,TRUE
.endif
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDOK
invoke _SendData
.endif
;********************************************************************
.elseif eax == WM_CLOSE
invoke closesocket,hSocket
invoke WSACleanup
invoke EndDialog,hWinMain,NULL
;********************************************************************
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
call _Init
;********************************************************************
上页:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(1) 下页:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(3)