为什么在原始套接字上关闭/关闭后,read()不返回?

离开迈耶

我有一个线程可以像这样在循环中从原始HCI套接字读取消息:

void* loop_hci (void* args) {
    params_hci_t* params = (params_hci_t*) args;
    int result_hci = 0;
    uint8_t* buf_hci = calloc(1, HCI_EVENT_MAX_LENGTH);
    while (!poll_end()) {
        result_hci = read(params->hci_sock, buf_hci, HCI_EVENT_MAX_LENGTH);
        if (result_hci > 0) {
            // ... do stuff with the received data
        }
    }
    ancs_pdebug("HCI loop shutting down...");
    return NULL;    
}

poll_end()功能可以正常工作并达到预期的效果。它返回0,直到收到SIGINT信号为止,然后返回1。

在主线程中,我这样创建套接字:

hci_sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);

还有线程:

ph->hci_sock = hci_sock;
pthread_create(&t_hci, NULL, &loop_hci, ph);

然后过一会儿再这样调用shutdown(在主线程中):

shutdown(hci_sock, SHUT_RD);

我假设read()应该在我调用shutdown()之后返回,我在L2CAP套接字的不同线程中使用相同的方法,并且工作正常。但事实并非如此。pthread_join(t_hci, NULL)在主线程中的调用再也不会返回。

套接字工作正常。我可以从中读取消息。我也尝试调用close(在线程结束后执行此操作),但是结果是相同的。

可能是问题所在,还是我的假设错了?

罗道克

您遇到的问题可能是由于您处理套接字和多线程的方式所致。您不应该对原始套接字使用shutdown。它用于连接的套接字,我真的从未尝试过使用原始套接字或数据包套接字。但是有人建议杀死或取消一个线程,这是我所避免的,因为杀死线程是蛮力的,并且您有可能不按有序方式处置资源。相反,您应该以其他方式设计解决方案:

  1. 一种可能性是将非阻塞套接字与select,poll或epoll一起使用。您将有一个循环,等待选择/轮询/ epoll,直到套接字准备就绪或超时。当您要关闭套接字时,只需将一个变量(例如endLoop)设置为true即可指示轮询线程应退出循环。请参阅man进行选择:http : //man7.org/linux/man-pages/man2/select.2.html

  2. 例如,在Thrift服务器中使用的另一种可能性是使应用程序使用某些代码向其自身发送特殊消息。侦听线程取消阻止并读取此特殊消息,该消息指示其应检查是否必须完成侦听(例如,通过读取变量值)。

因此,当他的侦听线程正在侦听或读取时,主线程会将变量endLoop变量设置为true,指示其已完成,或者它将执行(2)来解除阻塞侦听线程。

这两个选项是解决问题的优雅方法。使用非阻塞套接字(1)或通过向自身发送消息来解除阻塞被阻塞的读取或侦听线程。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么在原始套接字上关闭/关闭后,read()不返回?

来自分类Dev

为什么关闭关闭弹出消息?

来自分类Dev

确定何时在Android上关闭套接字

来自分类Dev

Python套接字-为什么在发送多个消息后关闭连接?

来自分类Dev

为什么在运行方法中关闭套接字?

来自分类Dev

为什么Python io流无法在__del__上关闭?

来自分类Dev

getSession关闭套接字

来自分类Dev

关闭网络套接字

来自分类Dev

getSession关闭套接字

来自分类Dev

关闭关于盒子

来自分类Dev

发送失败后关闭套接字不会导致recv函数返回错误状态

来自分类Dev

从函数返回控制台对象后,paramiko /套接字关闭

来自分类Dev

使用 setockopt;当套接字从另一侧关闭时,read 返回 0 而不是 -1

来自分类Dev

如何在python程序中的Ctrl-C上关闭套接字连接

来自分类Dev

为什么套接字关闭后端口没有立即释放?

来自分类Dev

为什么我的套接字没有在服务器端关闭?

来自分类Dev

Golang关闭后保持文件服务套接字打开

来自分类Dev

仅在成功传输后关闭Greenlet中的TCP套接字

来自分类Dev

获取File()后无法关闭golang tcp套接字

来自分类Dev

创建ServerSocket(或套接字)后无法关闭JFrame

来自分类Dev

接收流后关闭套接字连接-Java

来自分类Dev

关闭套接字会关闭流吗?

来自分类Dev

何时关闭UDP套接字

来自分类Dev

SocketException:套接字已关闭

来自分类Dev

PoolingClientConnectionManager如何关闭套接字

来自分类Dev

从主线程关闭套接字

来自分类Dev

在 PHP 中关闭套接字

来自分类Dev

是什么导致Java TCP套接字关闭?

来自分类Dev

什么时候关闭Java中的套接字连接

Related 相关文章

热门标签

归档