如何完全停止正在监听的Socket 我的程序中有一个监听Socket,它对应一个监听线程,该线程中使用事件选择的方式监听FD_ACCEPT和FD_CLOSE;在外部的主线程中希望关闭该监听线程,使用closesocket不成功,因为waitfor函数不返回,不知道该如何做? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 主线程中多创建一个event在监听线程中使用WaitForMultipleObject,传入跟socket有关的那个event和主线程中创建的那个event,不要wait all要停止监听时,在主线程中调用SetEvent (主线程创建的那个event)这样监听线程中WaitFor会返回,监听线程这时候closesocket就可以了 我暂时是这样实现的:UINT WINAPI ListenThreadProc(LPDWORD pvData){ WSAEVENT wsaEvents[2]; SOCKET hSocket = (SOCKET)pvData[0]; wsaEvents[0] = (WSAEVENT)pvData[1]; // 主线程要求关闭时通知的事件对象 wsaEvents[1] = (WSAEVENT)pvData[2]; // 有网络事件时通知的事件对象 ///////////////////////////////////////////////////////////////////// // 等待并处理客户事件 DWORD dwWaitStatus; BOOL bExitThread = FALSE; WSANETWORKEVENTS NetworkEvents; while (!bExitThread) { // 等待客户加入或停止 IOCPServer... dwWaitStatus = WSAWaitForMultipleEvents(2, wsaEvents, FALSE, INFINITE, FALSE); switch(dwWaitStatus) { case WSA_WAIT_EVENT_0: // 主线程要求关闭 bExitThread = TRUE; // 退出线程 break; case WSA_WAIT_EVENT_0 + 1: // 网络事件 if (WSAEnumNetworkEvents(hSocket, wsaEvents[1], &NetworkEvents) != SOCKET_ERROR) { // 处理网络事件 } break; default: break; } } closesocket(hSocket); WSACloseEvent(wsaEvents[0]); WSACloseEvent(wsaEvents[1]); return 0;} xstring(麻雀) ,chenwhenlong(bester) 的方法是相同的,而且应该可行,我再试试。不过有没有办法使监听socket触发close的事件?相应的为每个客户端建立的线程是可以用closesocket触发close事件的。 FD_CLOSE 事件是对方调用 closesocket 时才会触发吧? 我就是调用了closesocket而没有触发close事件。 侦听的套接字不会产生 FD_CLOSE 事件。FD_CLOSE 事件是要对方断开连接时才会发生的。要是会发生 FD_CLOSE 事件,假设有 5 个client 进行连接,那不就要发生 FD_CLOSE 事件吗? 要是会发生 FD_CLOSE 事件,假设有 5 个client 进行连接,那不就要发生 5 个 FD_CLOSE 事件吗? 我在服务器端为每个客户端建立的socket及线程,服务器就是主动调用closesocket就能够触发FD_CLOSE事件。 先调用shutdown(),再调用closesocket()。因为closesocket只是使引用减1,当为零时,才关闭。 我使用为主线程增加事件的方式之后可以停止监听线程的运行。但是再次重新启动服务器时第一次调用StartServ失败,第二次就成功,错误是发生在bind函数。为什么?怎么解决?int CSocketServer::StartServ(){ if (m_ServiceState == SS_Started) { return SUCCESS; } sockaddr_in local;//本地服务器地址 HANDLE hThread;//监听线程句柄 DWORD dwThreadId;//监听线程Id //创建监听Socket m_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (m_sListen == SOCKET_ERROR) { m_iInitSuccess = FAULT; closesocket(m_sListen); return m_iInitSuccess; } //绑定 local.sin_addr.s_addr = inet_addr(m_cServerIP); local.sin_family = AF_INET; local.sin_port = htons(m_iServerPort); if (bind(m_sListen, (sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) { m_iInitSuccess = FAULT; closesocket(m_sListen); return m_iInitSuccess; } //监听 listen(m_sListen, m_iBacklog); }int CSocketServer::StopServ(){ SetEvent(m_MainEvent); shutdown(m_sListen, SD_BOTH); closesocket(m_sListen);} 肯定是端口还被占用着,所以bind不成功不知道你重新启动服务时, StopServ是不是被调用了查查看 侦听的套接字如何在服务器端主动产生 FD_CLOSE 事件?这个问题还没有解决。 listen的是不会产生FD_CLOSE事件的如果你硬是要这个事件的话就自己产生好了:if (closesocket(listenfd)!=SOCKET_ERROR) SendMessage(WM_XXXX,listenfd,FD_CLOSE);其中:listenfd是侦听的套接字WM_XXXX是你自己定义的SOCKET关闭的事件 请介绍下稀疏光流算法 双缓冲绘图位图 TEXTMETRICS 的问题 关于使用微软speechsdk读取wave文件时遇到的问题。 问个简单的算法问题 一个这样简单的问题怎么就没有人回答!!!!!!!!!!!! :)如何在应用程序里实现一个CDocument对应多个CView,请各位高手不吝赐教:) GetActiveObject为什么得不到指针? 关于js调用ocx返回BSTR的内存泄露问题 动态生成的一个CEdit对象,如何初始化并显示出来啊?请指教 怎样在对话框中加ToolBar? 工作线程中数据如何传递给界面线程?
我暂时是这样实现的:UINT WINAPI ListenThreadProc(LPDWORD pvData)
{
WSAEVENT wsaEvents[2];
SOCKET hSocket = (SOCKET)pvData[0];
wsaEvents[0] = (WSAEVENT)pvData[1]; // 主线程要求关闭时通知的事件对象
wsaEvents[1] = (WSAEVENT)pvData[2]; // 有网络事件时通知的事件对象 /////////////////////////////////////////////////////////////////////
// 等待并处理客户事件
DWORD dwWaitStatus;
BOOL bExitThread = FALSE;
WSANETWORKEVENTS NetworkEvents;
while (!bExitThread) {
// 等待客户加入或停止 IOCPServer...
dwWaitStatus = WSAWaitForMultipleEvents(2, wsaEvents, FALSE,
INFINITE, FALSE);
switch(dwWaitStatus) {
case WSA_WAIT_EVENT_0: // 主线程要求关闭
bExitThread = TRUE; // 退出线程
break; case WSA_WAIT_EVENT_0 + 1: // 网络事件
if (WSAEnumNetworkEvents(hSocket, wsaEvents[1], &NetworkEvents)
!= SOCKET_ERROR)
{
// 处理网络事件
}
break; default:
break;
}
}
closesocket(hSocket);
WSACloseEvent(wsaEvents[0]);
WSACloseEvent(wsaEvents[1]);
return 0;
}
不过有没有办法使监听socket触发close的事件?相应的为每个客户端建立的线程是可以用closesocket触发close事件的。
FD_CLOSE 事件是要对方断开连接时才会发生的。要是会发生 FD_CLOSE 事件,假设有 5 个client 进行连接,那不就要发生 FD_CLOSE 事件吗?
因为closesocket只是使引用减1,当为零时,才关闭。
int CSocketServer::StartServ()
{
if (m_ServiceState == SS_Started)
{
return SUCCESS;
} sockaddr_in local;//本地服务器地址
HANDLE hThread;//监听线程句柄
DWORD dwThreadId;//监听线程Id //创建监听Socket
m_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (m_sListen == SOCKET_ERROR)
{
m_iInitSuccess = FAULT;
closesocket(m_sListen);
return m_iInitSuccess;
}
//绑定
local.sin_addr.s_addr = inet_addr(m_cServerIP);
local.sin_family = AF_INET;
local.sin_port = htons(m_iServerPort);
if (bind(m_sListen, (sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
m_iInitSuccess = FAULT;
closesocket(m_sListen);
return m_iInitSuccess;
} //监听
listen(m_sListen, m_iBacklog);
}int CSocketServer::StopServ()
{
SetEvent(m_MainEvent);
shutdown(m_sListen, SD_BOTH);
closesocket(m_sListen);
}
如果你硬是要这个事件的话就自己产生好了:
if (closesocket(listenfd)!=SOCKET_ERROR)
SendMessage(WM_XXXX,listenfd,FD_CLOSE);其中:
listenfd是侦听的套接字
WM_XXXX是你自己定义的SOCKET关闭的事件