WIN32汇编语言教程:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(4)

wClientPort    dw    ?

dwID              dd    ?

dwRetryTimes      dd    ?

 

CLIENT_ADDR    ends

;####################################################################

; 数据段

;####################################################################

                 .data?

hWinMain          dd    ?

hSocket       dd    ?

dwID              dd    ?

szReadBuffer      db    32768 dup (?)

szBuffer          db    32768 dup (?)

stTable       CLIENT_ADDR MAX_SOCKET dup (<>)

                  .const

szErrBind      db     '无法绑定到UDP端口9 999,请检查是否有其他程序在使用!',0

szFormat           db     '【客户端#%d】- %s',0dh,0ah,0

;####################################################################

; 代码段

;####################################################################

                  .code

;####################################################################

; 将有回复的客户端(表示还在聊天中)地址添加到列表中

;####################################################################

_AddSocket    proc      _lpSocket

 

;********************************************************************

; 查找地址是否存在,已存在则不必添加且重新设置应答计数器

;********************************************************************

                  mov    esi,offset stTable

                  mov    edi,_lpSocket

                 assume esi:ptr CLIENT_ADDR

                  assume edi:ptr sockaddr_in

                 xor    ebx,ebx

                 .while ebx <  MAX_SOCKET

                          mov    ax,[edi].sin_port

                          mov    ecx,[edi].sin_addr

                          .if    (ax == [esi].wClientPort)\

                                  && (ecx == [esi].dwClientIP)

                                 mov    [esi].dwRetryTimes,5

                                 ret

                          .endif

                          add    esi,sizeof CLIENT_ADDR

                          inc    ebx

                  .endw

;********************************************************************

; 否则在客户端地址表中找一个空的表项,并添加当前地址

;********************************************************************

                 mov    esi,offset stTable

                 xor    ebx,ebx

                  .while ebx <  MAX_SOCKET

                         .if    ! [esi].dwRetryTimes

                                  push      esi

                                inc    dwID

                                push      dwID

                                pop    [esi].dwID

                                 mov    [esi].dwRetryTimes,RETRY_TIMES

                                push      [edi].sin_addr

                                pop    [esi].dwClientIP

                                 mov    ax,[edi].sin_port

                                mov    [esi].wClientPort,ax

                                 pop    esi

                                 ret

                          .endif

                          add    esi,sizeof CLIENT_ADDR

                         inc    ebx

                  .endw

                 xor    esi,esi

                  assume esi:nothing

                  assume edi:nothing

                  ret

 

_AddSocket    endp

;####################################################################

; 处理接收到的UDP包

;####################################################################

_RecvData     proc      _hSocket

                 local  @dwRecv,@dwStructSize

                 local  @stSin:sockaddr_in

                  local  @dwCount

 

      mov    @dwStructSize,sizeof sockaddr_in

          invoke RtlZeroMemory,addr szReadBuffer,sizeof szReadBuffer

          invoke RtlZeroMemory,addr @stSin,sizeof @stSin

          invoke recvfrom,_hSocket,addr szReadBuffer,sizeof szReadBuffer,\

                  0,addr @stSin,addr @dwStructSize

          .if    eax != SOCKET_ERROR

                  mov    @dwRecv,eax

;********************************************************************

; 登记客户端ID,并转换字符串格式

;********************************************************************

                  invoke _AddSocket,addr @stSin

                  .if    ! esi

                        ret

                  .endif

                 assume esi:ptr CLIENT_ADDR

                 invoke wsprintf,addr szBuffer,addr szFormat,\

                         dword ptr [esi].dwID,addr szReadBuffer

;********************************************************************

; 如果不是回复字符 -1 的话,则按照客户端列表逐一发送

;********************************************************************

                  .if    dword ptr szReadBuffer != -1

                          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 szBuffer

                          mov    esi,offset stTable

                          xor    ebx,ebx

                          mov    @dwCount,ebx

;********************************************************************

                  .while ebx <  MAX_SOCKET

                         .if    dword ptr [esi].dwRetryTimes

                                 push      [esi].dwClientIP

                                 pop    @stSin.sin_addr

                                  mov    ax,[esi].wClientPort

                                 mov    @stSin.sin_port,ax

                                  invoke lstrlen,addr szBuffer

                                 mov    ecx,eax

                                 invoke sendto,hSocket,addr szBuffer,ecx,\

                                         0,addr @stSin,sizeof sockaddr_in

                                 dec    dword ptr [esi].dwRetryTimes

                                  .if    dword ptr [esi].dwRetryTimes

                                          inc    @dwCount

                                 .else

                                         invoke RtlZeroMemory,esi,\

                                                 sizeof CLIENT_ADDR

                                 .endif

                          .endif

                         add    esi,sizeof CLIENT_ADDR

上页:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(3) 下页:第16章 TCP/IP和网络通信 · 16.4 UDP协议编程(5)

第16章 TCP/IP和网络通信

版权所有 © 云南伯恩科技 证书:粤ICP备09170368号