winsock2开发网络程序时,我感到最让我关心的问题(相信对大家也是
最关键的问题),就是如果客户机与服务器套接字相互间发生数据传输
时,用什么机制来让接收的套接字进行接收,我查了大量的网上资料和
书,仍感不解.
1-有的网页举例用对话框中加定时器,每隔一定时间间隔执行接收;
2-有说用WSAAsyncSelect注册网络事件,当发生网络事件时,再发送自定消息,
  我在试这个方法时遇到这个问题,我在一个按钮中加入初始化套接字及listen,
  WSAAsyncSelct等,但只是在点击此按钮一次后,可接收到一次客户机的
  FD_ACCEPT网络事件,就是说每次须点击一次这个按钮后,才可接收到客户机的
  网络事件,而点击后此对话框未死住,因此我想应该已是非阻塞了,但如果用
  这个WSAAsyncSelect模式应当用什么机制来检测随时发生的网络事件呢?
  请各路高手给讲讲吧,谢谢啦.
3-我更想用书上说更好一些的WSAEventSelect模式,但这个是用while语句来
  不断的检测网络事件吗?请高手指点指点啊?

解决方案 »

  1.   

    WSAAsyncSelect(sock , hWnd , UM_READ , FD_READ|FD_CLOSE)函数执行后,系统会自动监视端口上的各种事件读,写,连接。如上利,如果端口上有数据到达或者发出的话,socket就会自动给应用程序发送UM_READ消息。(消息是我自定义的)
      

  2.   

    补充,每次执行WSAAsyncSelect()后 上一次的执行结果回作废,系统会自动监视新的事件!!如你说的,接受联接的以后,在接受联接的函数里重写WSAAsyncSelect(sock , hWnd , UM_READ , FD_READ)不管什么时候,只要有数据到达,socket就会给系统发送UM_READ消息。而不是用while
      

  3.   

    在winsock2的第二种I/O模式中,WSAAsyncSelect模式时,我也写了自定义的
    消息,但就象以上写的第二条中,那个按钮只在点击击一次后,当客户机发送数据时,只接收到一次FD_ACCEPT网络事件,之后客户发数据就无网络事件被收到了,为什么呢?
      

  4.   

    是UM_READ消息?????资料上都是说是网络事件都以FD_开头的呀???????
    如果是UM_READ消息,那怎么收到这个消息????????????????????
      

  5.   

    UM_READ是我自己定义的消息!!不是系统消息。
    WSAAsyncSelect(sock , hWnd , UM_READ , FD_READ|FD_CLOSE)系统会自动监视端口上的读和关闭。当有这两种事件时。会给hWnd指定的应用程序,发送UM_READ,消息,应用程序里 CASE ; UM_READ
     ……
     break;就可以处理了
      

  6.   

    啊,是这样,用第二种winsock I/O时,即WSAEventSelect时,是注册以FD_为开头的网络事件,当网络上发生事件时,会引发自定义的消息,就是你刚刚说的UM_READ,但是我遇到这种情况是:不是每次都引发自定义消息?
      

  7.   

    比如说,第一次要读数据
    你就WSAAsyncSelect(sock , hWnd , UM_READ , FD_READ)
    处理完接受的数据后在执行一次
    WSAAsyncSelect(sock , hWnd , UM_*** , FD_***)
    就可以处理新的事件了,
    另外!一个程序里FD_ACCEPT只能接受一次!
      

  8.   

    我的一个例子!
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch( message ) 
    {     case UM_ACCEPT: OnAccept(hWnd);
    break;

    case UM_READ: OnRead(hWnd,lParam);
    break;
               ……………………
               }
    }void OnRead(HWND hWnd, LPARAM lParam)
    {
    if (WSAGETSELECTEVENT(lParam) == FD_READ)
    {
    status=recv(sock,SoRBuf,sizeof(SoRBuf),0);
    if(status == SOCKET_ERROR)
    {
    MessageBox(hWnd,TEXT("Recive Error "),TEXT("ERROR"),MB_OK);
    WSACleanup();
    EnableMenuItem(GetMenu( hWnd ), IDM_SERVER, MF_ENABLED );
    }
    else
    {
    status=WSAAsyncSelect(sock , hWnd , UM_READ , FD_READ|FD_CLOSE);
    if(status==SOCKET_ERROR)
    {
    MessageBox(NULL,TEXT("WSAAsyncSelect ERROR"),TEXT("ERROR at OnRead"),MB_OK);
    WSACleanup();
    EnableMenuItem(GetMenu( hWnd ), IDM_SERVER, MF_ENABLED );
    }
    PutRichText(hInfoRich);
    }
    }
    else if(WSAGETSELECTEVENT(lParam) == FD_CLOSE)
    {
    MessageBox(hWnd,TEXT("CLOSE"),TEXT("my socket connect lost"),MB_OK);
    status=WSAAsyncSelect(sock , hWnd , 0 ,0);
    if(status==SOCKET_ERROR)
    {
    MessageBox(NULL,TEXT("ERROR"),TEXT("WSAAsyncSelect error"),MB_OK);
    WSACleanup();
    PostQuitMessage(0);
    }
    EnableMenuItem(GetMenu( hWnd ), IDM_SERVER, MF_ENABLED);
    EnableMenuItem(GetMenu( hWnd ), IDM_CLIENT, MF_ENABLED);
    }
    }
      

  9.   

    谢谢,我知道winsock2 的I/O模型有5种,
    1-select;2-WSAAsyncSelect;3-WSAEventSelect;4-重叠I/O(很象第三种的);
    5-完成端口;说是一种比一种好啊;
    那书上的一段代码(第三种)用的就是while