请问一个关于socket的问题,不是很难,请各位指教. 小弟做一个聊天室的程序,但是现在的问题是我用FD_CLOSE判断客户端离开聊天室,但是我不知道是那个客户端离开?请问要用什么语句?我是用数组来存放客户端的连接的.例如 scoket clientsocket[20]这样每有一个客户端连接就分配一个数组.但是当他们断线的时候我不知道是那个离开了.请您指教.应该如何写这个语句????谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你用的是MFC的CAsyncsocket或Csocket 还是socket api 如果你用的是CAsyncsocket或Csocket的话,又重载了OnClose,并在这里处理FD_CLOSE消息的话,那么接收到消息的这个类对象就是对应的离开的用户。可以这样找出其在客户端连接数组中的位置:OnClose(...){ ...... for(int i=0;i<20;i++) { if(this==&clientsocket[i]) { // 如果这个判断成立,那么此时的i就对应用户连接的socket在数组中的下标 } } ......} 你能得到FD_CLOSE,不管你用什么方法,都应该能得到该事件对应的socket吧然后在你的数组中遍历,比较就是了 用Wait的结果可以查到数组的位置 用的是api啊.请问如何写?用HeavenS(King Of Terran) 的方法可以吗? HeavenS(King Of Terran)的方法试过了不行啊.我用的是api请问如何写啊?多谢指教. WinSock API来说,SOCKET的值是唯一的标识,只有用这个来判断哪个套接字断开了,所以如果是聊天室的话,你必须用一个关联,比如你可以建立一个数据结构struct client{ SOCKET s; //对应的socket int nID; //聊天室内用户的id号};客户进入聊天室时填充client结构。当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。如果你用MFC Socket的话,那就比较简单了,因为搜索功能在CAsyncSocket中的DoCallBack中已经实现了,你可以看看sockcore.cpp文件。 kbkman(万岁爷)就用你的办法,当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。请问这个代码如何写?给点代码啊.谢谢 如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。 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; } /*这里是处理代码 */ } 上面的代码是临时写的,没编译过,不过大致思路是这样的,《windows网络编程》上有很详细的介绍 如果为FD_CLOSE,加这个处理代码 if(NetworkEvents.lNetworkEvents&FD_CLOSE) { if(NetworkEvents.iErrorCode[FD_CLOSE_BIT]!=0) { AfxMessageBox("套接字accept出错"); pThis->LogEvent(NULL,"套接字错误","套接字accept出错"); continue; } /*这里是处理代码 */ } 我的建议是最好不用fd_close 而是自己发出心跳包来维持客户端与服务器之间的联系 这样在一段时间服务器端收不到客户端发过来的心跳包时 能够主动去释放该客户端的套节字资源 Bright008(晓勇) ------------------------------如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。-----------------------------请问如何处理这个wParam函数来识别是那个socket阿?请给出代码如何处理wparam.谢谢各位! 请教:CTabCtrl::drawItem 不被调用的原因 我的对话框程序在最小化后再打开时表格变灰了,什么都看不到 很久不来了,散分 一个关于图片存储的问题 紧急求助,关于CPropertySheet 请问用微软MS XML读取XML时如何对付不同的日期格式? 自制浏览器时,网页弹出一个msg对话框后为什么不能自动刷新? vc6/MDI project ,如何捕获“当前Active的子视图窗口被切换改变“的消息? 又一程序问题,再线等待,高分赠送 浏览器访问gsoap服务端问题 如何禁止用户修改时间? web应用服务器组件资源如何释放
{
......
for(int i=0;i<20;i++)
{
if(this==&clientsocket[i])
{
// 如果这个判断成立,那么此时的i就对应用户连接的socket在数组中的下标
}
}
......
}
然后在你的数组中遍历,比较就是了
struct client
{
SOCKET s; //对应的socket
int nID; //聊天室内用户的id号
};客户进入聊天室时填充client结构。
当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。如果你用MFC Socket的话,那就比较简单了,因为搜索功能在CAsyncSocket中的DoCallBack中已经实现了,你可以看看sockcore.cpp文件。
就用你的办法,当FD_CLOSE时,搜索所有client结构,比较其中的s,如果相等就知道其聊天室的id了。
请问这个代码如何写?给点代码啊.谢谢
如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。
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;
}
/*
这里是处理代码
*/
}
if(NetworkEvents.lNetworkEvents&FD_CLOSE)
{
if(NetworkEvents.iErrorCode[FD_CLOSE_BIT]!=0)
{
AfxMessageBox("套接字accept出错");
pThis->LogEvent(NULL,"套接字错误","套接字accept出错");
continue;
}
/*
这里是处理代码
*/
}
在一段时间服务器端收不到客户端发过来的心跳包时 能够主动去释放该客户端的套节字资源
------------------------------
如果使用的Windosw API即(SDK),当收到FD_CLOSE消息时,Windows回调函数的wParam参数即为与客户通信的socket的句柄,此socket对应的客户你是应该知道的。
-----------------------------
请问如何处理这个wParam函数来识别是那个socket阿?请给出代码如何处理wparam.谢谢各位!