在Socket中阻塞方式下,accept的问题.

souhay 2004-07-10 12:04:53
我开了个线程用accept去得到新的SOCKET,当主线要退出时,怎么让while循环break?

while(1) { /* main accept() loop */
   sin_size = sizeof(struct sockaddr_in);
   if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,&sin_size))
{
………………
}
   }


...全文
304 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jdzwq 2004-07-11
  • 打赏
  • 举报
回复
线程的控制应该采用通用和安全的办法,在Win32中我是用如下方法的:
定义主线程控制块:
typdef struct _parent_block
{
BOOL acitve;
HANDLE events[MAX_THREADS];
int event_count; /*有效事件计数*/
.../*其他主线程变量*/
}parent_block;

定义子线程控制块:
typedef struct _child_block
{
parent_block* ptr_pb; /*主线程控制块指针*/
HANDLE* ptr_event /*该子线程占用的事件句柄的指针*/
... /*其他子线程变量*/
}child_block;

1。主线程控制块在主线程初始化时被创建
parent_block* ppb = (parnet_block*)calloc(1,sizeof(parent_block));
ppb->active = TRUE;
ppb->event_count = 0;

2。主线程为每一个子线程创建一个事件,并将子线程控制块指针传入子线程
ppb->events[ppb->event_count ++] = CreatEvent(NULL,TRUE,FALSE,NULL);/*事件的初始态为 no signed */
child_block* pcb = (child_block*)calloc(1,sizeof(child_block));
pcb->ptr_pb = ppb;
pcb->ptr_event = &(ppb->events[ppb->event_count -1]);
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)you_thread_proc,(LPVOID)pcb,0,,&dwid);

3。当主线程退出时,控制块active置为FALSE,并等待所有子线程的退出事件
...
ppb->active = FALSE;
WSACleanup();
WaitForMultipleObjects(ppb->event_count,ppb->events,TRUE,INFINITE);
for(i=0;i<ppb->event_count;i++)
closehandle(ppb->events[i];
free(ppb);
...

4.在子线程中作如下处理
DWORD you_thread_proc(LPVOID param)
{
child_block* pcb = (child_block*)param;
...
while(pcb->ptr_ppb->active == TRUE)
{
.../*your accept code here*/
}
SetEvent(*(pcb->ptr_event)); /*set event to singed*/
free(pcb);
.../*exit*/
}

5.以上仅用于静态线程管理,对于动态线程管理,主线程控制块中的事件数组应用动态数组管理,并在子线程退出时,将事件从数组中删除。
souhay 2004-07-11
  • 打赏
  • 举报
回复
jdzwq(zwq)方法我也想到过.但在阻塞状态下accept是等在那边的。我想用select应该可能解决。
sevencat 2004-07-11
  • 打赏
  • 举报
回复
设定超时。隔会儿去看看要不要关闭。
comman_wang 2004-07-11
  • 打赏
  • 举报
回复
在阻塞状态下accept线程是处于等待状态的,想BREAK循环,可能不太容易。
简单的方法(不一定正确):
随着程序一起强制退出,terminatethread,然后再closesocket。
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
呵呵,看看这个FAQ吧,我昨晚上刚整理的^_^

http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=196461

---------------------------------------------------------------

方法1 :

其实最简单的办法就是在程序退出的时候调用WSACleanup();就得了

WinSock会自动收回申请的资源

-----------------------------------------------------------------

方法2:

在监听的函数recv里面自己设定

比如收到"[exit]"这样的字符,就调用AfxEndThread或者直接return结束线程自身

------------------------------------------------------------------

方法3:

我用的是 WSAEventSelect,本来等几个 WSAEVENT 就可以了,结果我多加一个 WSAEVENT,而这个 WSAEVENT 和网络事件无关,仅仅只在主程序想结束该辅助线程时被传信,那么主程序结束时,传信该 WSAEVENT,辅助线程那边 WSAEventSelect 就有动静了,然后就可以自己收尾退出了。

-----------------------------------------------------------------------

方法4:

同时检测网络事件(FD_ACCEPT)(m_hNetEvent)和线程关闭事件(m_hExitEvent),如果是m_hExitEvent, 就结束线程
Aries1979 2004-07-10
  • 打赏
  • 举报
回复
你设置一个全局变量
比如:bool g_exit = false;

while(1)
{
(g_exit)
break;
.......// your accept code here
}
^_^
souhay 2004-07-10
  • 打赏
  • 举报
回复
我有好几个线程都用到了SOCKET,不能WSACleanup();来退出的。
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
什么意思?

其实如果嫌麻烦,while循环不用退出,随着程序一起强制退出也行

只要程序退出的时候加上WSACleanup();就OK了
souhay 2004-07-10
  • 打赏
  • 举报
回复
WSAEventSelect我这里没有办法。
#include <Winsock2.h>之后,出现很多的错误。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧