一段防止数据包粘连代码的疑问
时间:2011-02-18
来源:互联网
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 阻塞模式下使用的常用子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在规定的时间内等待数据到达
; 输入:dwTime = 需要等待的时间(微秒)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WaitData proc _hSocket,_dwTime
local @stFdSet:fd_set,@stTimeval:timeval
mov @stFdSet.fd_count,1
push _hSocket
pop @stFdSet.fd_array
push _dwTime
pop @stTimeval.tv_usec
mov @stTimeval.tv_sec,0
invoke select,0,addr @stFdSet,NULL,NULL,addr @stTimeval
ret
_WaitData endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 接收规定字节的数据,如果缓冲区中的数据不够则等待
; 返回:eax = TRUE,连接中断或发生错误
; eax = FALSE,成功
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RecvData proc _hSocket,_lpData,_dwSize
local @dwStartTime
mov esi,_lpData
mov ebx,_dwSize
invoke GetTickCount
mov @dwStartTime,eax
;********************************************************************
@@:
invoke GetTickCount ;查看是否超时
sub eax,@dwStartTime
cmp eax,10 * 1000
jge _Err
;********************************************************************
invoke _WaitData,_hSocket,100*1000 ;等待数据100ms
cmp eax,SOCKET_ERROR
jz _Err
or eax,eax
jz @B
invoke recv,_hSocket,esi,ebx,0
.if (eax == SOCKET_ERROR) || ! eax
_Err:
xor eax,eax
inc eax
ret
.endif
.if eax < ebx
add esi,eax
sub ebx,eax
jmp @B .endif
xor eax,eax
ret
_RecvData endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 接收一个符合规范的数据包
; 返回:eax = TRUE (失败)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RecvPacket proc _hSocket,_lpBuffer,_dwSize
local @dwReturn
pushad
mov @dwReturn,TRUE
mov esi,_lpBuffer
assume esi:ptr MSG_STRUCT
;********************************************************************
; 接收数据包头部并检测数据是否正常
;********************************************************************
invoke _RecvData,_hSocket,esi,sizeof MSG_HEAD
or eax,eax
jnz _Ret
mov ecx,[esi].MsgHead.dwLength
cmp ecx,sizeof MSG_HEADjb _Ret
cmp ecx,_dwSize
ja _Ret
;********************************************************************
; 接收余下的数据
;********************************************************************
sub ecx,sizeof MSG_HEAD
add esi,sizeof MSG_HEAD
.if ecx
invoke _RecvData,_hSocket,esi,ecx
.else
xor eax,eax
.endif
mov @dwReturn,eax
_Ret:
popad
assume esi:nothing
mov eax,@dwReturn
ret
_RecvPacket endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
看不懂的是上面的红色地方,invoke _RecvData,_hSocket,esi,sizeof MSG_HEAD
在调用_RecvData这个子程序后,recv有两种情况,一种是刚好得到这个数据包头的长度,那就跳过子程序的绿色部分
这时候并没有对esi进行改变,这没问题
第二种revt得到的数据长度小于数据包头的长度,那就要执行绿色部分的代码,对esi进行修改。。可是函数并没有对esi进入push pop操作,这样_RecvData返回后,esi的值不是变了吗,这样回到主函数_RecvPacket代码mov ecx,[esi].MsgHead.dwLength这句话不是有问题了吗?
有知道的原因的朋友说下,谢谢。。。
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 阻塞模式下使用的常用子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在规定的时间内等待数据到达
; 输入:dwTime = 需要等待的时间(微秒)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WaitData proc _hSocket,_dwTime
local @stFdSet:fd_set,@stTimeval:timeval
mov @stFdSet.fd_count,1
push _hSocket
pop @stFdSet.fd_array
push _dwTime
pop @stTimeval.tv_usec
mov @stTimeval.tv_sec,0
invoke select,0,addr @stFdSet,NULL,NULL,addr @stTimeval
ret
_WaitData endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 接收规定字节的数据,如果缓冲区中的数据不够则等待
; 返回:eax = TRUE,连接中断或发生错误
; eax = FALSE,成功
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RecvData proc _hSocket,_lpData,_dwSize
local @dwStartTime
mov esi,_lpData
mov ebx,_dwSize
invoke GetTickCount
mov @dwStartTime,eax
;********************************************************************
@@:
invoke GetTickCount ;查看是否超时
sub eax,@dwStartTime
cmp eax,10 * 1000
jge _Err
;********************************************************************
invoke _WaitData,_hSocket,100*1000 ;等待数据100ms
cmp eax,SOCKET_ERROR
jz _Err
or eax,eax
jz @B
invoke recv,_hSocket,esi,ebx,0
.if (eax == SOCKET_ERROR) || ! eax
_Err:
xor eax,eax
inc eax
ret
.endif
.if eax < ebx
add esi,eax
sub ebx,eax
jmp @B .endif
xor eax,eax
ret
_RecvData endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 接收一个符合规范的数据包
; 返回:eax = TRUE (失败)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RecvPacket proc _hSocket,_lpBuffer,_dwSize
local @dwReturn
pushad
mov @dwReturn,TRUE
mov esi,_lpBuffer
assume esi:ptr MSG_STRUCT
;********************************************************************
; 接收数据包头部并检测数据是否正常
;********************************************************************
invoke _RecvData,_hSocket,esi,sizeof MSG_HEAD
or eax,eax
jnz _Ret
mov ecx,[esi].MsgHead.dwLength
cmp ecx,sizeof MSG_HEADjb _Ret
cmp ecx,_dwSize
ja _Ret
;********************************************************************
; 接收余下的数据
;********************************************************************
sub ecx,sizeof MSG_HEAD
add esi,sizeof MSG_HEAD
.if ecx
invoke _RecvData,_hSocket,esi,ecx
.else
xor eax,eax
.endif
mov @dwReturn,eax
_Ret:
popad
assume esi:nothing
mov eax,@dwReturn
ret
_RecvPacket endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
看不懂的是上面的红色地方,invoke _RecvData,_hSocket,esi,sizeof MSG_HEAD
在调用_RecvData这个子程序后,recv有两种情况,一种是刚好得到这个数据包头的长度,那就跳过子程序的绿色部分
这时候并没有对esi进行改变,这没问题
第二种revt得到的数据长度小于数据包头的长度,那就要执行绿色部分的代码,对esi进行修改。。可是函数并没有对esi进入push pop操作,这样_RecvData返回后,esi的值不是变了吗,这样回到主函数_RecvPacket代码mov ecx,[esi].MsgHead.dwLength这句话不是有问题了吗?
有知道的原因的朋友说下,谢谢。。。
作者: yg30hxj 发布时间: 2011-02-18
没人知道原因吗
作者: yg30hxj 发布时间: 2011-02-20
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28