accept如何退出问题

来源:互联网 发布:监控画面无网络视频 编辑:程序博客网 时间:2024/04/28 07:32

  今天想到一个问题,监听线程一般在死循环中调用accept函数,没有连接时就阻塞,但是主线程退出时如何让其一起退出?找了找发现了标准的做法。

1、accept的写法

  socket = WSAAccept(m_socket, ……);

    if(socket == INVALID_SOCKET)

        continue;

2、主线程写法

    shutdown(m_socket, SD_BOTH);

    closesocket(m_socket);

 
  网上找来的其他本法,貌似有理,但是感觉还是个很别扭的方法。

 (zt)accept阻塞时退出程序问题
写过socket的朋友们一定都有过这样的经历:程序想退出的时候,却发现被accept阻塞着,此时,想退出程序只能强行杀死。多进程多线程的时候这个问题尤其严重,曾经在网上查了很多资料,也没有人给个好的解决方法,只有用select实行非阻塞模式,直到今天,这个问题终于找到了一个完美的解决方案(非select,socket阻塞模式时,linux下编程已测)。 简单说说我的实现方式吧:信号+longjmp。 伪代码如下:
int main()
{
    socket s;
    ...
    bind(s);
    ...
    socket ns = accept();//此处就是让我们头疼的地方了。 ...
}
 
只需要在代码上稍作修改,就可以实现退出阻塞模式的accept了。想退出此程序时,只需要向该程序发送一个SIGIO的信号即可了^_^。
static jmp_buf jmpbuf;
static void sig_quit(int signo)
{
    longjmp(jmpbuf, 1);
}
int main()
{
    socket s;
    singal(SIGIO, sig_quit);
    ...
    bind(s);
    ...
    if(setjmp(jmpbuf)) {
        exit(0);
    }
    socket ns = accept();//即使堵在此也不怕了
    ...
}
 
简单说下原理吧,这个是使用了SIGIO可打断阻塞程序的原理,跳出accept阻塞,又利用了longjmp可以跳出函数的原理,彻底摆脱accept的束缚,很简单,不知道当初为啥一直没想到,受了accept多年的折磨。windows下应该也会有相应的消息+跳转机制与之对应,我不太熟,就不给举例子了。感兴趣的可以试试我这个方法,我目前只在linux下试过,不知道unix和其他类unix系统是否好用,仅希望此文能能抛砖引玉,让大家有更好更方便的方案发出来给大家分享一下。