您的位置:程序门 -> delphi -> 网络通信/分布式开发



请教关于函数wsaresetevent的问题。


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


请教关于函数wsaresetevent的问题。[已结贴,结贴人:piaoxueskysz]
发表于:2008-01-22 14:14:10 楼主
上次文了一个关于tclientwinsocket的问题。非常感谢"僵哥"的回答。经过几天的反反复复的修改测试。终于有点眉目了。
代码是这样的。
    fsocket   :=   tclientwinsocket.create(integer(not(0)));
    //采用阻塞模式
    fsocket.clienttype   :=   ctblocking;


    try
        fsocket.open(fhost,   fhost,   '',   8309);   //连接服务端
        timeout   :=   2000;                                             //2秒超时
        hadsendconn   :=   false;
        setsockopt(fsocket.sockethandle,   sol_socket,   so_rcvtimeo,   @timeout,   sizeof(timeout));
    except
    end;
    peekmessage(msg,   0,   0,   0,   pm_noremove);
    event   :=   wsacreateevent;     //创建事件句柄
    try
        wsaeventselect(fsocket.sockethandle,   event,   fd_read   or   fd_close);
        while   (not   terminated)   and   (fsocket.connected=true)   do
            case   msgwaitformultipleobjects(1,   event,   false,   500,   qs_allinput)   of
                //接收网络消息部分
                wait_object_0:
                begin
                    if   isclose(fsocket.sockethandle,   event)   then
                    begin
                        {   'server   close'   ;   }
                        break;
                    end;
                      //***********接收数据部分*********************
                    retlen   :=   fsocket.receivebuf(d.content,   d.len);
                    //**********如果接收到非法消息,程序continue
                    wsarecmsg   :=   d.content;
                    postmessage(frm_wyclientmain.handle,wm_getmes,wparam(wsarecmsg),length(wsarecmsg));
                    //***********接收数据结束*********
                    //************重置事件句柄*********
                    //关键是这句。如果接收到合法消息程序会到这里,事件对象状态清除为未置信号
                      //也就是这样一句,可能使我的socket连接存在,但是永远不会进入到读状态。
                      wsaresetevent(event);
                  //********************************
                end;
                wait_object_0   +   1:
                begin
                    //发送网络消息部分
                    if   peekmessage(msg,   0,   0,   0,   pm_remove)   then
                        begin
                            case   msg.message   of
                                wm_user:
                                begin
                                    //发送自定义消息   如   登陆,注销等
                                end;
                                wm_close:
                                begin
                                    //发送客户端正常关闭消息
                                    //正常退出,服务端会对数据库做相应操作
                                    //退出线程
                                          break;
                                end;
                          end;
                      end;
                end;
                wait_timeout:
                begin
                    //线程启动时发送连接消息
                      if   hadsendconn   =   false   then
                    begin
                        //置已连接标志为真
                        hadsendconn   :=   true;
                    end;
                end;
              end;
    finally
        wsacloseevent(event);
    end;


上次僵哥说要我全部用api函数,他说可能tclientwinsocket会与我的代码有冲突。但是改了后还是一样。现在的问题是这个函数wsaresetevent跟我的程序逻辑是不是冲突,请高手看一下。为什么会这样呢?是不是本身我就不应该使用这个函数在这里重置。。
请高手出马啊。。。。。。。。。
发表于:2008-01-22 15:03:391楼 得分:100
tclientwinsocket继续于tcustomwinsocket,其open方法在tcustomwinsocket当中有实现。当采用block模式,在open调用过程当中就会调用tcustomwinsocket.doopen,而doopen又会调用tcustomwinsocket.dosetasyncstyles,在dosetasyncstyles当中则有一个wsaasyncselect,而这之后,楼主再调用wsaeventselect,你觉得系统会听谁的?
发表于:2008-01-22 15:11:272楼 得分:0
msdn当中有这样一段描述,issuing   a   wsaeventselect   for   a   socket   cancels   any   previous   wsaasyncselect   or   wsaeventselect   for   the   same   socket   and   clears   the   internal   network   event   record.意思也就是wsaeventselect是可以覆盖掉原来的wsaasyncselect,但是如果服务器是一个主动服务(比如smtp服务等有欢迎消息发送的,或者是完全主动推送的,那么在被覆盖掉之前会是什么情况?

另外peekmessage当中,除了上面的几个消息,以后的消息怎么办?就算是独立的线程,那如果里面还有别的如ttimer,那么这个wm_timer消息不就丢弃了?

另外还是之前提到过的那个同步的问题。postmessage不等待消息的处理。wsarecmsg会是怎么样的一种情况?
发表于:2008-01-23 11:00:283楼 得分:0
谢谢。。。。
昨天终于发现了,原来问题不再这里段代码,而在我服务端。服务端可以正常发送心跳消息,客户端也可以正常接收、发送消息。只是服务端接收客户端消息有阻塞。导致socket连接正常,客户端可以正常收发情况下,服务端不能返回消息。就算是我知道了这种情况,释放掉原来连接重新建立的服务端线程还是不能启动。
呵呵。害的搞了几天一直以为客户端同步或是阻塞的问题。
谢谢僵哥。分继续给上。


快速检索

最新资讯
热门点击