2014-03-07 17 views
0
int CreateSocket() 
{ 
    socklen_t len; 

    // Socket creation for UDP 

    acceptSocket=socket(AF_INET,SOCK_DGRAM,0); 

    if(acceptSocket==-1) 

    { 

    printf("Failure: socket creation is failed, failure code\n"); 

    return 1; 

    } 

    else 

    { 

    printf("Socket started!\n"); 

    } 

memset(&addr, 0, sizeof(addr)); 

addr.sin_family=AF_INET; 

addr.sin_port=htons(port); 

addr.sin_addr.s_addr=htonl(INADDR_ANY); 

rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr)); 

if(rc== -1) 

{ 

    printf("Oh dear, something went wrong with bind()! %s\n", strerror(errno)); 

    return 1; 

} 

else 

{ 

    printf("Socket an port %d \n",port); 
} 

    while(rc!=-1) 
    { 
     fd_set master; 
     fd_set read_fds; 
     int retval; 
     FD_ZERO(&master); 
     FD_ZERO(&read_fds); 
     FD_SET(acceptSocket, &master); 
     FD_SET(acceptSocket, &read_fds); 
     retval =select(2, &master, NULL, NULL, NULL); 
     len = sizeof(client); 
     if(retval == -1) 
     { 
      printf("error\n"); 
     } 
     else if(FD_ISSET (acceptSocket, &master)) 
     { 
    rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len); 
    if(rc==0) 
    { 
     printf("Server has no connection..\n"); 
     break; 
    } 
    if(rc==-1) 
    { 
     printf("Oh dear, something went wrong with read()! %s\n", strerror(errno)); 
     break; 
    } 
    XcpIp_RxCallback((uint16) rc, (uint8*) buf, (uint16) port); 

     } 

     else 
     { 
      makeTimer("First Timer", &firstTimerID, 2, 2); //2ms 
          makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms 
          makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms 

     } 


    } 


    close(acceptSocket); 



    return 0; 
    } 

以上是udp層通過ip地址和端口號從客戶端接收數據的服務器代碼。我正在使用select api來檢查通過端口是否有數據,然後接收數據,否則調用定時器函數。我想實現從客戶端接收數據,並在收到我必須調用計時器。但是上面的代碼沒有調用定時器任務。上面代碼中的錯誤是什麼?使用select api有效嗎?如何在udp中使用select api for linux

回答

0

的第一個參數來選擇()是1 +編號最高的FD-在-的三集,所以應acceptSocket + 1

(我假設你真正的問題是更比上面的代碼複雜,因爲你可以做一個阻塞recvfrom()調用而不用打擾select()。如果你想在單個線程中處理多個套接字,你需要select()和/或喚醒阻塞在超時後呼叫 - 雖然還有其他的方式來做後者)。

+0

怎麼樣?民意調查 – kiran

+0

有沒有其他解決方案? – kiran

0

你打電話的方式select()timeout == NULL它將阻塞,直到在中有一個文件描述符要讀取數據。在你的情況下,與master只包含acceptSocketelse你撥打makeTimer()永遠不會到達。

struct timeval timeout; 

timeout.tv_sec = 0l; 
timeout.tv_usec = 0l; 
retval = select(acceptSocket+1, master, NULL, NULL, &timeout); 

只檢查不阻塞

注意select()返回0,如果返回,因爲超時而包含在返回的描述符的設置,否則文件描述符的數量。所以,你也必須改變你的條件:

else if(FD_ISSET (acceptSocket, &master)) 

else if(retval > 0 && FD_ISSET (acceptSocket, &master)) 

,否則你會召喚timout後recvfrom(),以及在這種情況下,它會阻止

+0

如果我給它如下,那麼它將是5微秒 - 它是否? \t time.tv_sec = 5; \t time.tv_usec = 1; – kiran

+0

'time.tv_sec = 5' - > 5秒。對於5微秒,將'tv_sec'設置爲0並將'tv_usec'設置爲5; –

+0

非常感謝你!它不是從recvfrom api出來的? – kiran

相關問題