2016-11-04 51 views
0

我製作了一個程序,用於監聽特定的ipv6地址和端口,它顯示接收到的內容。我的程序完美運作;我還沒有測試過所有的東西,但基本的使用方法是有效的。在c中連續接收udp套接字

我需要你對這個問題的建議:連續聽最好的方法是什麼?

當我啓動程序時,我想通過在shell中使用Ctrl+C來停止監聽。但是,如果我這樣做,一些重要的代碼可能不會執行。以下是我在我的主要函數的末尾:

while(1){ 

     // reception de la chaine de caracteres 
     if(recvfrom(sockfd, buf, 1024, 0 
        , (struct sockaddr *) &client, &addrlen) == -1) 
     { 
      perror("recvfrom"); 
      close(sockfd); 
      exit(EXIT_FAILURE); 
     } 

     buf[1023] = '\0'; 

     // print the received char 
     printf("%s", buf); 
    } 


    // close the socket 
    close(sockfd); 

    return 0; 

首先,我認爲這是消極等待,因爲函數recvfrom,直到它收到的東西停止程序。所以使用一段時間不是問題。問題是,close(sockfd)可能不會被執行。

所以我正在尋找一種簡單的方法來停止程序時執行一些代碼。我想到了線程,但這對於這個問題可能太複雜了。

+0

通常你會處理由ctrl-c產生的信號。人的信號。 – Claris

+0

如果程序退出,系統將關閉其所有文件描述符。如果這些文件描述符中的一個(或多個)是套接字,則該套接字關閉。 –

回答

1

是的,你可以捕捉到ctrl-c信號並在收到該信號後執行代碼。

#include<stdio.h> 
#include<signal.h> 
#include<unistd.h> 

void sig_handler(int signo) 
{ 
    if (signo == SIGINT) 
    printf("received SIGINT\n"); 
} 

int main(void) 
{ 
    if (signal(SIGINT, sig_handler) == SIG_ERR) 
    printf("\ncan't catch SIGINT\n"); 
    // A long long wait so that we can easily issue a signal to this process 
    while(1) 
    sleep(1); 
    return 0; 
} 
+1

請參閱[如何避免在信號處理程序中使用'printf()'](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler/16891799#16891799 )。 –

+0

我做到了,我在主體中創建了一個函數來訪問關閉套接字的函數。但是現在當我停止程序時,我得到了這個:'recvfrom:壞文件描述符',我認爲它來自while循環中的'perror',因爲recvfrom也可能捕獲到'SIGINT'信號,你怎麼看? –

+1

@KevinM聽起來好像你在你的信號處理程序運行後回到'recvfrom()'循環。清理完成後,您需要退出程序。 – Barmar