小弟做一个聊天室的程序,但是现在的问题是我用FD_CLOSE判断客户端离开聊天室,但是我不知道是那个客户端离开?请问要用什么语句?我是用数组来存放客户端的连接的.例如 scoket clientsocket[20]
这样每有一个客户端连接就分配一个数组.但是当他们断线的时候我不知道是那个离开了.请您指教.应该如何写这个语句????谢谢

解决方案 »

  1.   

    你用的是MFC的CAsyncsocket或Csocket 还是socket api
      

  2.   

    如果你用的是CAsyncsocket或Csocket的话,又重载了OnClose,并在这里处理FD_CLOSE消息的话,那么接收到消息的这个类对象就是对应的离开的用户。可以这样找出其在客户端连接数组中的位置:OnClose(...)
    {
        ......
        for(int i=0;i<20;i++)
        {
            if(this==&clientsocket[i])
            {
                // 如果这个判断成立,那么此时的i就对应用户连接的socket在数组中的下标
            }
        }
        ......
    }
      

  3.   

    你能得到FD_CLOSE,不管你用什么方法,都应该能得到该事件对应的socket吧
    然后在你的数组中遍历,比较就是了
      

  4.   

    用Wait的结果可以查到数组的位置
      

  5.   

    用的是api啊.请问如何写?用HeavenS(King Of Terran) 的方法可以吗?
      

  6.   

    HeavenS(King Of Terran)的方法试过了不行啊.我用的是api请问如何写啊?多谢指教.
      

  7.   

    WinSock API来说,SOCKET的值是唯一的标识,只有用这个来判断哪个套接字断开了,所以如果是聊天室的话,你必须用一个关联,比如你可以建立一个数据结构
    struct client
    {
         SOCKET s;     //对应的socket
         int    nID;   //聊天室内用户的id号
    };客户进入聊天室时填充client结构。
    当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。如果你用MFC Socket的话,那就比较简单了,因为搜索功能在CAsyncSocket中的DoCallBack中已经实现了,你可以看看sockcore.cpp文件。
      

  8.   

    kbkman(万岁爷)
    就用你的办法,当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。
    请问这个代码如何写?给点代码啊.谢谢
      

  9.   


    如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。
      

  10.   

    memset(&NetworkEvents,0,sizeof(WSANETWORKEVENTS));
    index=WSAWaitForMultipleEvents(m_SocketNum,
    pThis->m_hListenEvent,
    FALSE,
    1000000,//waitting for ever
    FALSE);
    if (index == WSA_WAIT_TIMEOUT)
    {
    MsgBox("等待客户连接超时");
    continue;
    }
    int SockNum=index-WAIT_OBJECT_0;
    int ret= WSAEnumNetworkEvents(pThis->m_hListenSock[SockNum],
     pThis->m_hListenEvent[SockNum],
     &NetworkEvents);
    if(NetworkEvents.lNetworkEvents&FD_ACCEPT)
    {
    if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
    {
    AfxMessageBox("套接字accept出错");
    pThis->LogEvent(NULL,"套接字错误","套接字accept出错");
    continue;
    }
    /*
    这里是处理代码
    */

    }
      

  11.   

    上面的代码是临时写的,没编译过,不过大致思路是这样的,《windows网络编程》上有很详细的介绍
      

  12.   

    如果为FD_CLOSE,加这个处理代码
    if(NetworkEvents.lNetworkEvents&FD_CLOSE)
    {
    if(NetworkEvents.iErrorCode[FD_CLOSE_BIT]!=0)
    {
    AfxMessageBox("套接字accept出错");
    pThis->LogEvent(NULL,"套接字错误","套接字accept出错");
    continue;
    }
    /*
    这里是处理代码
    */

    }
      

  13.   

    我的建议是最好不用fd_close 而是自己发出心跳包来维持客户端与服务器之间的联系 这样
    在一段时间服务器端收不到客户端发过来的心跳包时 能够主动去释放该客户端的套节字资源
      

  14.   

    Bright008(晓勇) 
    ------------------------------
    如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。
    -----------------------------
    请问如何处理这个wParam函数来识别是那个socket阿?请给出代码如何处理wparam.谢谢各位!