📄 ciowork.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 + -