2016-11-01 4 views
0

スレッドを使用して、バックグラウンドでUDPサーバを起動したいと考えました。 しかし、サーバーは、パケットが受信されたかどうかを永久にチェックしてループします。 代わりにTCPサーバーを使用すると、同じスレッドが正常に機能します。あなたがここに1つの深刻な問題を抱えているCスレッドを使用しているバックグラウンド上のUDPサーバ

int udp_server_listen() { 
    printf("udp_server_listen \n"); 
    int res;  
    unsigned char rsp_buf[1024]; 
    struct sockaddr_in src; 
    socklen_t srclen; 
    memset(&src, 0, sizeof(src)); 
    srclen = sizeof(src); 

    listen(s , 3); 

    //Accept and incoming connection 
    int c = sizeof(struct sockaddr_in); 
    int client_sock; 
    while((client_sock = accept(s, (struct sockaddr *)&src, (socklen_t*)&c))) 
    { 
     sleep(1); 
     printf("OK \n"); 
    } 
} 

void *thread_udp_cr_listen (void *v) 
{ 
    udp_server_listen(); 
    return NULL; 
} 

int s; 
int main() 
{ 
    printf("start test \n"); 

    struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in *));  
    s = socket(AF_INET, SOCK_DGRAM, 0); // UDP 
    printf("create socket end\n"); 
    int reusaddr = 1; 
    int reusport = 1; 
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) 
    { 
     printf("setsockopt(SO_REUSEADDR) failed \n"); 
    } 
    if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reusport, sizeof(int)) < 0) 
    { 
     printf("setsockopt(SO_REUSEPORT) failed \n"); 
    } 
    struct timeval tv; 
    tv.tv_sec = 2; /* 30 Secs Timeout */ 
    tv.tv_usec = 0; // Not init'ing this can cause strange errors 
    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); 
    fcntl(s, F_SETFL, O_NONBLOCK); 
    printf(" Bind to a specific network interface and a specific local port\n"); 
    int i = 0; 
    for(;i<6;i++) 
    { 
      if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) 
      { 
       printf("bind Faild %d\n", i); 
       sleep(1); 
       continue; 
      } 
     break; 
    }  
    error = pthread_create(&udp_cr_server_thread, NULL, &thread_udp_cr_listen, NULL); 
    if (error<0) 
    { 
     printf("thread error \n"); 
    } 
    pthread_join(udp_cr_server_thread, NULL); 
} 
+0

UDPは*接続されていない*プロトコルですか?あなたはTCPのように接続を受け入れず、代わりにデータグラムだけを受信します。 –

+1

あなたは 'local'ソケットアドレスのポインタを使わないということで多くの問題を解決できます。 –

+0

あなたは正確に何をしたいのか説明できますか?あなたは、データグラムを永遠に待つコードを書いています。それがあなたが望むものではないなら、あなたは何を望みますか? –

答えて

2

テストコードは次のようである

struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in *));  

あなただけではなく、構造体のサイズのポインタのサイズを割り当てているので、自体。

これは当然のようになります。この行で同じ変数を持つ

struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in));  


さらに二つの問題:

 if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) 

これは次のようになります。あなたが知っています

 if (bind(s, (struct sockaddr *)local, sizeof(*local)) < 0) 
関連する問題