⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ciowork.asm

📁 一个采用汇编线程池实现的Socket完成端口编程例程。
💻 ASM
字号:
;工作者线程
_ServerWorkProc PROC uses esi _lParam:DWORD
   LOCAL @hCompletionPort :DWORD
   LOCAL @BytesRecv       :DWORD
   LOCAL @dwFlags         :DWORD
   LOCAL @lpContext       :DWORD
   LOCAL @dwReturn        :DWORD
   LOCAL @Overlapped      :OVERLAPPED
   LOCAL @hClass          :DWORD
   
;===========================================================================
;9.等待完成端口消息,未收到消息德时候则阻塞线程
;===========================================================================
   xor    esi,esi
   m2m    @hCompletionPort,_lParam
   .while TRUE
      invoke GetQueuedCompletionStatus,@hCompletionPort, \
                                       addr @BytesRecv, \
                                       addr @lpContext, \
                                       addr @Overlapped, \
                                       INFINITE
      mov    @dwReturn,eax
      .if eax==0
         ;method @hClass,CLS_IOSKT,SetLastErr,CTEXT("服务器投递接收准备 失败")
         jmp    @F
      .endif
      
      mov    esi,@lpContext
      m2m    @hClass,(SOCKETCONTEXT ptr [esi]).hClass

;===========================================================================
;10.清理客户端退出信息
;===========================================================================
      .if @BytesRecv==0
         method @hClass,CLS_IOSKT,SetWarning,CTEXT("清理客户端退出信息 提示")
         invoke closesocket,(SOCKETCONTEXT ptr [esi]).hAccept
         .if eax== SOCKET_ERROR
            method @hClass,CLS_IOSKT,SetLastErr,CTEXT("清理客户端退出信息 失败")
            .break
         .endif
         invoke GlobalFree,esi
         .continue
      .endif
   
;===========================================================================
;11.处理接收的客户端信息
;===========================================================================
      mov    eax,(SOCKETCONTEXT ptr [esi]).dwIoFlag
      .if eax==OP_READ          ;从服务器端读到消息
         mov    (SOCKETCONTEXT ptr [esi]).SendSize ,0
         mov    (SOCKETCONTEXT ptr [esi]).BytesSend,0
         m2m    (SOCKETCONTEXT ptr [esi]).BytesRecv,@BytesRecv
         ;===========================================================================
         ;接收信息完成,在这儿增加对接收到的代码进行处理,回传信息后加
         ;===========================================================================
         ;回传接收到的消息
         invoke RtlMoveMemory,addr (SOCKETCONTEXT ptr [esi]).Buffer,addr szSend,sizeof szSend
         
         ;初始化缓冲区
         mov    (SOCKETCONTEXT ptr [esi]).SendSize ,sizeof szSend
         mov    (SOCKETCONTEXT ptr [esi]).BytesSend,0
         mov    (SOCKETCONTEXT ptr [esi]).dwIoFlag ,OP_WRITE
         
         invoke RtlZeroMemory,addr (SOCKETCONTEXT ptr [esi]).Overlapped,sizeof OVERLAPPED
         
         m2m    (SOCKETCONTEXT ptr [esi]).DataBuf.len,(SOCKETCONTEXT ptr [esi]).SendSize
         lea    eax,(SOCKETCONTEXT ptr [esi]).Buffer
         mov    (SOCKETCONTEXT ptr [esi]).DataBuf.buf,eax
         
         mov    @dwFlags,0
         invoke WSASend,(SOCKETCONTEXT ptr [esi]).hAccept, \
                        addr (SOCKETCONTEXT ptr [esi]).DataBuf,1, \
	                addr @BytesRecv,0, \
	                addr (SOCKETCONTEXT ptr [esi]).Overlapped,NULL
         .if eax==SOCKET_ERROR
            invoke WSAGetLastError
            .if eax!=ERROR_IO_PENDING
               method @hClass,CLS_IOSKT,SetLastErr,CTEXT("投递发送信息 失败")
               .break
            .endif
         .endif
         .continue
      .else                                     ;写消息的通知
         mov    eax,@BytesRecv           ;数据发送完成或部分发送,部分发送需要移动指针后重发
         add    (SOCKETCONTEXT ptr [esi]).BytesSend,eax             ;部分发送时(SOCKETCONTEXT ptr [esi]).SendSize>(SOCKETCONTEXT ptr [esi]).BytesSend
         mov    eax,(SOCKETCONTEXT ptr [esi]).SendSize
         sub    eax,(SOCKETCONTEXT ptr [esi]).BytesSend
         .if eax>0                                                  ;发送未完成,需要重新投递发送请求〖数据未发送完,需要移动到后面指针发送〗
            invoke RtlZeroMemory,addr (SOCKETCONTEXT ptr [esi]).Overlapped,sizeof OVERLAPPED
            lea    eax,(SOCKETCONTEXT ptr [esi]).Buffer             ;以绝对地址向后移动数据指针【何时还原指针?投递完成后还原】
            add    eax,(SOCKETCONTEXT ptr [esi]).BytesSend
            mov    (SOCKETCONTEXT ptr [esi]).DataBuf.buf,eax
            mov    eax,(SOCKETCONTEXT ptr [esi]).SendSize
            sub    eax,(SOCKETCONTEXT ptr [esi]).BytesSend
            mov    (SOCKETCONTEXT ptr [esi]).DataBuf.len,eax        ;剩下需要发送的数据大小
            invoke WSASend,(SOCKETCONTEXT ptr [esi]).hAccept, \
                           addr (SOCKETCONTEXT ptr [esi]).DataBuf,1, \
			   addr @BytesRecv,0, \
			   addr (SOCKETCONTEXT ptr [esi]).Overlapped,NULL
            .if eax==SOCKET_ERROR
               invoke WSAGetLastError
               .if eax!=ERROR_IO_PENDING
                  method @hClass,CLS_IOSKT,SetLastErr,CTEXT("投递未发送信息 失败")
                  .break
               .endif
            .endif
            .continue
         .endif
      .endif
;===========================================================================
;12.重新投递接收的IO覆盖指令
;===========================================================================
      ;初始化缓冲区
      mov    (SOCKETCONTEXT ptr [esi]).SendSize ,0                              ;初始化缓冲区,并投递一个接收的准备
      mov    (SOCKETCONTEXT ptr [esi]).BytesRecv,0
      mov    (SOCKETCONTEXT ptr [esi]).BytesSend,0
      mov    (SOCKETCONTEXT ptr [esi]).dwIoFlag ,OP_READ
      
      invoke RtlZeroMemory,addr (SOCKETCONTEXT ptr [esi]).Buffer,DATA_BUFSIZE  ;缓冲区信息
      invoke RtlZeroMemory,addr (SOCKETCONTEXT ptr [esi]).Overlapped,sizeof OVERLAPPED
      
      mov    (SOCKETCONTEXT ptr [esi]).DataBuf.len,DATA_BUFSIZE
      lea    eax,(SOCKETCONTEXT ptr [esi]).Buffer
      mov    (SOCKETCONTEXT ptr [esi]).DataBuf.buf,eax

      mov    @dwFlags,0
      invoke WSARecv,(SOCKETCONTEXT ptr [esi]).hAccept, \
                     addr (SOCKETCONTEXT ptr [esi]).DataBuf,1, \
                     addr @BytesRecv,
                     addr @dwFlags,
                     addr (SOCKETCONTEXT ptr [esi]).Overlapped,NULL
      .if eax==SOCKET_ERROR
         invoke WSAGetLastError
         .if eax!=ERROR_IO_PENDING
            method @hClass,CLS_IOSKT,SetLastErr,CTEXT("服务器投递接收准备 失败")
            jmp    @F
         .endif
      .endif
   .endw
@@:   
   ret
_ServerWorkProc ENDP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -