首页 文章

什么是关闭套接字的风险,通过接受在另一个线程中使用?

提问于
浏览
0

我有一个服务器应用程序 .

服务器正在尝试从线程中的客户端连接:

while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
     .....
 }

我有另一个在我的应用程序的退出中执行的线程 . 在这个线程中我关闭套接字 socket_desc

close(socket_desc);

在线程中关闭套接字的风险是什么,还有另一个线程在同一个套接字上接受?

3 回答

  • 1

    据我所知,您描述的操作组合的语义没有定义,这应该足以让您找到替代方案 . 我推测合理可能观察到的行为包括

    • close() 快速返回,并且

    • accept() 调用快速失败,可能表示 EBADFEINVALENOTSOCK 错误,或者

    • accept() 呼叫继续阻止,直到连接请求到达,或

    • accept() 无限期地阻止呼叫;要么

    • close() 阻止,直到 accept() 返回,如果有的话;要么

    • close()accept() 死锁 .

    但是,如果确实没有定义语义,那么几乎任何事情都可能发生 .

    如果一个不同的线程必须关闭套接字而不是它上面的一个连接,那么你应该明智地设置某种标志来指示程序正在退出,然后 accept() accept() ing线程将其从 accept() 中分离出来 . 接收到这种信号的线程将从程序退出标志知道停止而不是再次尝试 accept() .

    如果您的线程可以取消,那么全局标志可以采用线程取消消息的形式 . accept() 函数是取消点,因此您的线程将在下次调用 accept() 之前收到取消消息 .

  • 1

    我错了 . 但是,它可能适用于这样的场景: - 考虑3个线程 - A,B,C .

    • 线程A等待套接字并进入休眠状态

    • 线程B关闭套接字

    • 线程C创建一个新的套接字,它恰好获得与最近关闭的套接字相同的文件描述符编号(套接字也是一个文件)

    • 线程A唤醒( accept 上有错误代码),然后调用 close 认为意外错误=>这会影响在C中创建的完全不同的有效套接字!!

  • 0

    您可以关闭套接字以中止accept函数 . 但是您必须更改代码,并仔细检查API函数的返回值 . while循环中的尝试不起作用,因为它不检查SOCK_ERROR(-1) .

相关问题