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

📄 ciostart.asm

📁 一个采用汇编线程池实现的Socket完成端口编程例程。
💻 ASM
字号:
    IOSKT_Start PROC uses edi esi lpTHIS:DWORD,_dwPortNum:DWORD,_lpServerWorkProc:DWORD
       LOCAL  @stInetAddr:sockaddr_in
       LOCAL  @stSysInfo :SYSTEM_INFO 
       LOCAL  @dwLoops   :DWORD
       LOCAL  @hThread   :DWORD
       LOCAL  @dwThreadID:DWORD
       LOCAL  @hAccept   :DWORD
       LOCAL  @hCompPort :DWORD
       LOCAL  @dwFlags   :DWORD
       LOCAL  @RecvBytes :DWORD
       
       SetObject edi,CLS_IOSKT
       invoke RtlZeroMemory,addr @stInetAddr,sizeof @stInetAddr
       mov    esi,0
;===========================================================================
;1.创建完成端口
;===========================================================================
       invoke CreateIoCompletionPort,INVALID_HANDLE_VALUE,NULL,0,0
       mov    [edi].m_hCompPort,eax
       .if eax==NULL
          invoke IOSKT_SetLastErr,lpTHIS,CTEXT("CreateIoCompletionPort 失败")
          jmp    @F
       .endif
;===========================================================================
;2.检测系统信息
;===========================================================================
       invoke RtlZeroMemory,addr @stSysInfo,sizeof @stSysInfo
       invoke GetSystemInfo,addr @stSysInfo
;===========================================================================
;3.创建服务线程,数量为CPU*2
;===========================================================================
       mov    eax,2
       mul    @stSysInfo.dwNumberOfProcessors
       mov    @dwLoops,eax
       xor    ebx,ebx
       .while ebx<@dwLoops
          invoke CreateThread,NULL,NULL,_lpServerWorkProc,[edi].m_hCompPort,0,addr @dwThreadID
          mov    @hThread,eax
          .if eax==NULL
             invoke IOSKT_SetLastErr,lpTHIS,CTEXT("建立线程池线程 失败") 
             jmp    @F
          .endif
          invoke CloseHandle,@hThread                               ;关闭句柄,能避免线程异常退出资源泄露
          inc    ebx
       .endw
;===========================================================================
;4.创建监听Socket
;===========================================================================
       invoke WSASocket,AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED
       .if eax==INVALID_SOCKET
          invoke IOSKT_SetLastErr,lpTHIS,CTEXT("WSAsocket 失败")
          jmp    @F
       .endif
       mov    [edi].m_hListen,eax

       mov    @stInetAddr.sin_family,AF_INET
       invoke htonl,INADDR_ANY
       mov    @stInetAddr.sin_addr.S_un.S_addr,eax
       invoke htons,_dwPortNum
       mov    @stInetAddr.sin_port,ax
       invoke bind,[edi].m_hListen,addr @stInetAddr,sizeof @stInetAddr
       .if eax == SOCKET_ERROR
          invoke IOSKT_SetLastErr,lpTHIS,CTEXT("bind端口 失败")
          jmp    @F
       .endif
       
       invoke listen,[edi].m_hListen,5                              ;开始监听,指定最大同时连接数为5
       .if eax==SOCKET_ERROR
          invoke IOSKT_SetLastErr,lpTHIS,CTEXT("启动侦听listen 失败")
          jmp    @F
       .endif
;===========================================================================
;5.开始接收从客户端来的连接
;===========================================================================
       .while TRUE                                                  ;循环等待连接,然后由线程处理连接
          invoke WSAAccept,[edi].m_hListen,NULL,NULL,NULL,0
          mov    @hAccept,eax
          .if eax== SOCKET_ERROR
             invoke IOSKT_SetLastErr,lpTHIS,CTEXT("接受客户端连接 失败")
             jmp    @F
          .endif
;===========================================================================
;6.创建交换信息重叠结构关键项
;===========================================================================
          invoke GlobalAlloc,GPTR,sizeof SOCKETCONTEXT               
          mov    esi,eax
          .if eax==NULL
             invoke IOSKT_SetLastErr,lpTHIS,CTEXT("申请连接客户端数据交换内存 失败")
             jmp    @F
          .endif

          m2m    (SOCKETCONTEXT ptr [esi]).hListen,[edi].m_hListen
;===========================================================================
;7.将客户端关联到完成端口
;===========================================================================
          invoke CreateIoCompletionPort,@hAccept,[edi].m_hCompPort,esi,0
          mov    @hCompPort,eax
          .if eax==NULL
             invoke IOSKT_SetLastErr,lpTHIS,CTEXT("绑定到完成端口 失败")
             jmp    @F
          .endif
;===========================================================================
;8.投递一个接收的IO覆盖指令
;===========================================================================
          mov    (SOCKETCONTEXT ptr [esi]).SendSize ,0                             ;初始化缓冲区,并投递一个接收的准备
          mov    (SOCKETCONTEXT ptr [esi]).BytesSend,0
          mov    (SOCKETCONTEXT ptr [esi]).BytesRecv,0

          mov    (SOCKETCONTEXT ptr [esi]).dwIoFlag ,OP_READ                       ;参数信息
          m2m    (SOCKETCONTEXT ptr [esi]).hListen  ,[edi].m_hListen
          m2m    (SOCKETCONTEXT ptr [esi]).hAccept  ,@hAccept
          m2m    (SOCKETCONTEXT ptr [esi]).hCompPort,@hCompPort
          m2m    (SOCKETCONTEXT ptr [esi]).hClass   ,lpTHIS

          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 @RecvBytes, \
                         addr @dwFlags, \
                         addr (SOCKETCONTEXT ptr [esi]).Overlapped,NULL
          .if eax==SOCKET_ERROR
             invoke WSAGetLastError
             .if eax!=ERROR_IO_PENDING
                invoke IOSKT_SetLastErr,lpTHIS,CTEXT("CIoStart 服务器投递接收准备 失败")
                jmp    @F
             .endif
          .endif
       .endw
    @@:
       ReleaseObject edi
       
       ret
    IOSKT_Start ENDP
    
    IOSKT_Stop PROC uses edi lpTHIS:DWORD
    
       SetObject edi,CLS_IOSKT
       invoke shutdown,[edi].m_hListen,SD_BOTH
       invoke closesocket,[edi].m_hListen
       ReleaseObject edi
       ret
    IOSKT_Stop ENDP

⌨️ 快捷键说明

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