[英]To Stop server->how to verify if thread is stopped ->pthread
MAIN任務 ->客戶端斷開連接后立即停止服務器。
問題概述:我有一個非常大的應用程序,並且在該應用程序中,我實現了一個小的服務器代碼,該代碼接受連接並從客戶端接收數據包。
我想要的是只要客戶端已連接並正在發送數據包,服務器就不應斷開連接,但是一旦客戶端斷開連接 ,服務器也應停止運行。
為此,我創建了一個單獨的線程來接收來自客戶端的數據包,並且一旦客戶端與服務器斷開連接,該線程就會自動終止。
現在,我的下一個目標是找出分離的線程是否已完成,如果是,則關閉“ accept socket” (從下面的代碼中讀取其nsk變量)。 為此,我如何知道分離過程已完成? 我沒有從網上獲得太多信息。 其次,有人建議使用pthreadkill,但是為此我將如何找到pid?
有人可以請我保釋。
謝謝
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;
}
將整個服務器功能放到單個線程中,即accept()和recv()循環。 然后accept()將僅被調用一次,因此只能返回一次,因此將僅接受一個連接。 當客戶端斷開連接時(即recv()返回0),請通過關閉監聽套接字並終止線程來進行清理。 如果連接半關閉(例如,客戶端電源中斷),則該線程可能會永遠死纏,卡在recv()上,但是,嘿,誰在乎呢? 您可以使用KEEPALIVE最終關閉套接字並終止線程,但是並沒有真正的需要-它的代碼和堆棧最終將被分頁,並且它成為孤立的空間,丟失了(mehh..sob ..)。
哦-擺脫NON_BLOCKING了。 我不明白您為什么要首先設置它? 除了半封閉的情況外,您正在吸收一個核心,而幾乎沒有,在這種情況下,您吸收了一個核心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.