Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么在原始套接字上关闭/关闭后read()不返回?_C_Sockets_Bluetooth_Network Programming_Hci - Fatal编程技术网

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

C 为什么在原始套接字上关闭/关闭后read()不返回?,c,sockets,bluetooth,network-programming,hci,C,Sockets,Bluetooth,Network Programming,Hci,我有一个线程,它在循环中从原始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套接字读取消息,如下所示:

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;    
}
hci_sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
poll\u end()
函数工作正常,符合预期。它返回0,直到收到SIGINT信号,然后返回1

在主线程中,我创建了如下套接字:

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;    
}
hci_sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
还有线程:

ph->hci_sock = hci_sock;
pthread_create(&t_hci, NULL, &loop_hci, ph);
然后在一段时间后,像这样调用shutdown(在主线程中):

我假设read()应该在调用shutdown()后返回,我在L2CAP套接字的不同线程中使用了相同的方法,并且工作正常。但事实并非如此。主线程中的My
pthread\u join(t\u hci,NULL)
调用永远不会返回

这个插座很好用。我可以从中阅读信息。我还尝试调用close(在线程结束后调用),但是结果是一样的


可能是什么问题,或者我的假设是错误的?

您遇到的问题可能是因为您处理套接字和多线程的方式。您不应该对原始套接字使用shutdown。它是为连接的套接字设计的,我从来没有用原始套接字或数据包套接字尝试过。但是有一个建议是杀死或取消一个线程,我会避免这种情况,因为杀死一个线程是一种蛮力,并且您有可能无法按顺序处理资源。相反,您应该以不同的方式设计解决方案:

  • 一种可能是将非阻塞套接字与select、poll或epoll一起使用。您将有一个循环,它在select/poll/epoll中等待套接字准备就绪或超时。当您想要关闭一个套接字时,您只需将一个变量(例如endLoop)设置为true,指示轮询线程应该离开循环。有关选择,请参见man:

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

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


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

    您是否告诉线程退出?是否检查
    read
    以返回
    0
    -1
    ?如果
    read
    返回
    0
    -1
    ,是否中断循环或以其他方式结束线程?如果可能的话,请尝试创建一个并显示给我们。在我调用shutdown之前,会设置一个标志,以便poll_end()返回1。如果结果是您认为甚至允许对另一个线程正在使用的文件描述符调用
    shutdown()
    ?您可以发送信号(
    pthread\u kill()
    )或取消线程
    pthread\u cancel()
    。明智的方法是在非阻塞套接字上执行
    [e]poll()
    [p]select()
    shutdown()
    仅在TCP(SOCK\u流)套接字上执行任何操作。这是一个未加工的插座@EOF这在TCP套接字中是一种非常有效的技术,但在这里它不是TCP套接字。