首页
论坛
专栏
课程

[旧帖] [原创]罗云彬《32位汇编语言》16章中对TCP聊天室程序的扩展2 0.00元

2009-9-19 21:48 931

[旧帖] [原创]罗云彬《32位汇编语言》16章中对TCP聊天室程序的扩展2 0.00元

2009-9-19 21:48
931
第一步的功能已经实现了。下一步就是限制用户灌水了。
1.在Message.inc中,增加一个MSG_UP_RESP数据包,服务器端收到客户端发来的聊天语句时,如果判断本客户端此次的发言时间和上次的发言时间间隔太短,就向客户端发送带错误代码的MSG_UP_RESP数据包。

;**********************************************************        ;canmeng萌2
; 提示语句(服务器端->客户端)                                                                        ;canmeng萌2
;**********************************************************        ;canmeng萌2
MSG_UP_RESP                struct                                                ;canmeng萌2
  dbResult                db        ?                                                        ;canmeng萌2
MSG_UP_RESP                ends                                                ;canmeng萌2
②增加这个数据包的数据包头部命令ID
CMD_MSG_UP_RESP        equ                84h        ;服务器端 ->客户端,提示不可以灌水,canmeng萌2
③在MSG_STRUCT结构体中也增加一个MSG_UP_RESP类型的字段
MSG_STRUCT                struct
  MsgHead                MSG_HEAD <>
  union
    Login                MSG_LOGIN <>
    LoginResp                MSG_LOGIN_RESP <>
    MsgUp                MSG_UP <>
    MsgUpResp                MSG_UP_RESP <>                ;canmeng萌2
    MsgDown                MSG_DOWN <>
  ends
MSG_STRUCT                ends
2.在Server.asm中,在_ServiceThread子线程中定义一个局部变量@lasttime,用来记录本子线程和对应的客户端最近一次通话的时间。

local        @lasttime                                        ;canmeng萌2
②当服务器端的某个线程收到对应的客户端发来的聊天语句时,首先把此用户上次的发言时间赋给@lasttime,然后再调用GetTickCount函数得到现在的时间并赋给[edi].dwLastTime
两个进行比较,如果间隔小于设定的时间间隔(我设定为2秒),那么就向对应的客户端发送一个MSG_UP_RESP数据包,而且不把本次的聊天语句放进消息队列。
;********************************************************************
; 使用 select 函数等待 200ms,如果没有接收到数据包则循环
;********************************************************************
invoke        _WaitData,_hSocket,200 * 1000
.break        .if eax == SOCKET_ERROR
.if        eax
        invoke        _RecvPacket,_hSocket,esi,sizeof @szBuffer
        .break        .if eax
        mov eax,[edi].dwLastTime                                                                                ;canmeng萌2
        mov         @lasttime,eax                                                                                        ;canmeng萌2
        invoke        GetTickCount
        mov        [edi].dwLastTime,eax
        .if        [esi].MsgHead.dwCmdId == CMD_MSG_UP
        mov        ebx,[edi].dwLastTime                                                                                ;canmeng萌2
        sub        ebx,@lasttime                                                                                                ;canmeng萌2
        .if ebx<2000                                                                                                        ;canmeng萌2
                mov [esi].MsgHead.dwCmdId,CMD_MSG_UP_RESP                                ;canmeng萌2
                mov [esi].MsgHead.dwLength,sizeof MSG_HEAD+sizeof MSG_UP_RESP        ;canmeng萌2
                mov [esi].MsgUpResp.dbResult,1                                                        ;canmeng萌2
                invoke send,_hSocket,esi,[esi].MsgHead.dwLength,0        ;canmeng萌2
        .else                                                                                                                        ;canmeng萌2
                invoke        _InsertMsgQueue,addr [edi].szUserName,addr [esi].MsgUp.szContent
        .endif                                                                        ;canmeng萌2
        .endif
        .endif
.endw
3.在Client1.asm中,
①在.const段中定义一个变量zstoofast,当用户发言太快时就显示这个提示。
.const
sztoofast        db        '您的发言太快,请休息片刻',0                                ;canmeng萌2
②在_workThread的“循环接收消息”中进行判断,如果接受的数据包命令ID为CMD_MSG_UP_RESP,那么就显示一个消息框。
.if        @stMsg.MsgHead.dwCmdId == CMD_MSG_DOWN
……
.elseif        @stMsg.MsgHead.dwCmdId == CMD_MSG_UP_RESP                        ;canmeng萌2
        .if        @stMsg.MsgUpResp.dbResult==1                                                        ;canmeng萌2
        invoke        MessageBox,hWinMain,addr sztoofast,NULL,MB_OK                ;canmeng萌2
        .endif                                                                                                                        ;canmeng萌2
这样,第二步限制用户灌水也完成了。
附件是源代码。

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (1)
dxs党晨源 2009-9-21 22:53
2
0
赞!!!!!
游客
登录 | 注册 方可回帖
返回