简体   繁体   English

要停止服务器->如何验证线程是否已停止-> pthread

[英]To Stop server->how to verify if thread is stopped ->pthread

MAIN task -> to STOP Server as soon as client has disconnected. MAIN任务 ->客户端断开连接后立即停止服务器。

Overview of a problem: I have very large application and within that application, I have implemented a small server code which accept connection and receive packets from client. 问题概述:我有一个非常大的应用程序,并且在该应用程序中,我实现了一个小的服务器代码,该代码接受连接并从客户端接收数据包。
All I wanted is As long as client is connected and is sending packets, the server should not disconnect but as soon as client has disconnected , the server should also stop running. 我想要的是只要客户端已连接并正在发送数据包,服务器就不应断开连接,但是一旦客户端断开连接 ,服务器也应停止运行。

To Achieve this I have created a seperate thread that receive packets from client and this thread automatically terminates as soon as client disconnect istself from server. 为此,我创建了一个单独的线程来接收来自客户端的数据包,并且一旦客户端与服务器断开连接,该线程就会自动终止。

Now my next target is to find out if the detached thread has finished and if yes then close the "accept socket" ( from below code its nsk variable). 现在,我的下一个目标是找出分离的线程是否已完成,如果是,则关闭“ accept socket” (从下面的代码中读取其nsk变量)。 For this to achieve how would I know that detached process has finished? 为此,我如何知道分离过程已完成? I havn't got much information from net. 我没有从网上获得太多信息。 secondly, someone suggested to use pthreadkill but for that how would I find pid ? 其次,有人建议使用pthreadkill,但是为此我将如何找到pid?

Can someone please bail me out . 有人可以请我保释。
Thanks 谢谢

   static int sco_listen()
{
printf(" we are in sco_listen_function\n" );
    struct sockaddr_sco addr;
    struct sco_conninfo conn;
    socklen_t optlen;
    int sk, nsk;
    char ba[18];
    int *new_sock;

    /* Create socket */
    sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
    if (sk < 0) {
        syslog(LOG_ERR, "Can't create socket: %s (%d)",
                            strerror(errno), errno);
        exit(1);
    }

    /* Bind to local address */
    memset(&addr, 0, sizeof(addr));
    addr.sco_family = AF_BLUETOOTH;
    bacpy(&addr.sco_bdaddr, &bdaddr);

    if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        syslog(LOG_ERR, "Can't bind socket: %s (%d)",
                            strerror(errno), errno);
        goto error;
    }

    /* Listen for connections */
    if (listen(sk, 10)) {
        syslog(LOG_ERR,"Can not listen on the socket: %s (%d)",
                            strerror(errno), errno);
        goto error;
    }

    syslog(LOG_INFO,"Waiting for connection ...");
    while (1) 
    {
        memset(&addr, 0, sizeof(addr));
        optlen = sizeof(addr);

        nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
        if (nsk < 0) 
        {
            syslog(LOG_ERR,"Accept failed: %s (%d)",
                            strerror(errno), errno);
            goto error;
        }
        if( fcntl( nsk, F_SETFL, O_NONBLOCK ) < 0 )
        {
         printf(" failed to set non blocking ...\n");
         close( nsk );
         goto error;

        }

        /* Get connection information */
        memset(&conn, 0, sizeof(conn));
        optlen = sizeof(conn);

        if (getsockopt(nsk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0)
        {
            syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)",
                            strerror(errno), errno);
            close(nsk);
            goto error;
        }

        ba2str(&addr.sco_bdaddr, ba);
        syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]",
            ba, conn.hci_handle,
            conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]);

        pthread_t sniffer_thread;
        new_sock = malloc(1);
        *new_sock = nsk;

        if( pthread_create( &sniffer_thread, NULL, connection_handler, (void*)new_sock )< 0 )
        {
          perror(" could not create thread");
          return 1;

        }

        // HERE CHECK IF SNIFFER_THREAD IS RUNNING OR NOT. 
//IF SINIFFER THREAD IS NOT RUNNING THEN CLOSE NSK?
// ANd that will terminate the server?
        puts (" handler assigned");

    }

    return 0 ;

error:
    close(sk);
    exit(1);
}

void *connection_handler( void *socket_desc)
{
  // get socket descriptor
 int sock = *(int*)socket_desc;

 int read_size;

 char*message, message_client[ 200 ];

  //receive messgae from client 
 while( read_size = recv( sock, message_client, 200, 0 ) > 0 )
 {
   printf(" very good\n"); 
 }
 if( read_size == 0 )
 {
  printf("clinet disconnected \n");
  fflush( stdout);
 }
 else if( read_size == -1 )
 {
  printf("received failed \n"); 
  perror( " recv fialed");
 }

 printf(" before memeory freee\n");
 free( socket_desc );

 return 0;

}

Put the entire server functionality into a single thread, both the accept() and the recv() loop. 将整个服务器功能放到单个线程中,即accept()和recv()循环。 The accept() will then only ever be called once, so can only return once, so only one connection will ever be accepted. 然后accept()将仅被调用一次,因此只能返回一次,因此将仅接受一个连接。 When the client disconnects, (ie. recv() returns 0), clean up by closing the listening socket and terminating the thread. 当客户端断开连接时(即recv()返回0),请通过关闭监听套接字并终止线程来进行清理。 If the connection half-closes, (eg. power fail at client), the thread may hang around forever, stuck on the recv(), but hey, who cares? 如果连接半关闭(例如,客户端电源中断),则该线程可能会永远死缠,卡在recv()上,但是,嘿,谁在乎呢? You could use KEEPALIVE to eventually close the sockets and terminate the thread, but there's no real need for it - it's code and stack will eventually get paged out, and it's orphaned and lost in space, (mehh..sob..). 您可以使用KEEPALIVE最终关闭套接字并终止线程,但是并没有真正的需要-它的代码和堆栈最终将被分页,并且它成为孤立的空间,丢失了(mehh..sob ..)。

Oh - and get rid of the NON_BLOCKING. 哦-摆脱NON_BLOCKING了。 I don't understand why you set it in the first place? 我不明白您为什么要首先设置它? You're soaking up one core for next-to-nothing, except in the case of a half-close, in which case you're soaking up one core for absolutely nothing. 除了半封闭的情况外,您正在吸收一个核心,而几乎没有,在这种情况下,您吸收了一个核心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM