Linux程序設計之套接字:UDP

    編寫與客戶端之間維持連接的應用程序,我們用面向連接的TCP套接字來完成這一工作。但在有些情況下,在程序中花費時間來建立和維持一個套接字連接是不必要的。比如 daytime 服務,我們首先創建一個套接字,然後建立連接,讀取一個響應,最後關閉連接。在這一過程中,我們使用了很多操作步驟,僅僅爲了獲取一個日期。

     daytime 服務還可以用數據報通過UDP來訪問。爲了訪問它,發送一個數據報給該服務,然後在響應中獲取一個包含日期和時間的數據報。這一過程非常簡單。當客戶需要發送一個短小的查詢請求給服務器,並且期望接受到一個短小的響應時,我們一般使用由UDP提供的服務。如果服務器處理客戶請求的時間足夠短,服務器就可以通過一次處理一個客戶請求的方式來提供服務,從而允許操作系統將客戶進入的請求放入隊列。這簡化服務器程序的編寫。

    爲了使用UDP提供的服務,你需要像往常一樣使用套接字和 close 系統調用,但你需要用兩個數據報專用的系統調用 sendto 和 recvfrom 來代替使用TCP服務時的 read 和 write 調用。下面是一個簡單的示範程序,如有需要可以擴展其功能:

 

  1. /* server.cc */
  2.  
  3. #include <cstdio>                                                                 
  4. #include <cstdlib>
  5.                                                                                   
  6. #include "sys/socket.h"                                                           
  7. #include "netinet/in.h"                                                           
  8. #include "unistd.h"                                                               
  9.                                                                                   
  10. #define SRV_PORT 6500 

  11. using namespace std;                                                              
  12.                                                                                   
  13. char buffer[512];                                                                 
  14.                                                                                   
  15. int main(int argc, char *argv[])                                                  
  16. {                                                                                 
  17.     /* Create a UDP socket */                                                     
  18.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);                                  
  19.                                                                                   
  20.     /* Construct the address for use with sendto/recvfrom */                      
  21.     struct sockaddr_in address;                                                   
  22.     address.sin_family = AF_INET;                                                 
  23.     address.sin_addr.s_addr = htonl(INADDR_ANY);                                  
  24.     address.sin_port = htons(SRV_PORT);                                           
  25.     int len = sizeof(address);                                                    
  26.                                                                                   
  27.     /* Bind address to socket */                                                  
  28.     bind(sockfd, (struct sockaddr *)&address, sizeof(address));                   
  29.                                                                                   
  30.     /* serving */                                                                 
  31.     while(1) {                                                                    
  32.         /* receive */                                                             
  33.         recvfrom(sockfd, buffer, sizeof(buffer), 0,                               
  34.                  (struct sockaddr *)&address, (socklen_t *)&len);                 
  35.                                                                                   
  36.         /* handle */                                                              
  37.         sprintf(buffer, "i am server");                                           
  38.                                                                                   
  39.         /* response */                                                            
  40.         sendto(sockfd, buffer, sizeof(buffer), 0,                                 
  41.                (struct sockaddr *)&address, sizeof(address));                     
  42.                                                                                   
  43.     }                                                                             
  44.                                                                                   
  45.     /* close */                                                                   
  46.     close(sockfd);                                                                
  47.                  
  48.     return 0;                                                                     
  1. /* client.cc */
  2.  
  3. #include <cstdio>                                                                 
  4. #include <cstdlib>                                                                
  5.                                                                                   
  6. #include "arpa/inet.h"                                                            
  7. #include "sys/socket.h"                                                           
  8. #include "netinet/in.h"                                                           
  9. #include "unistd.h"                                                               
  10.                        
  11. #define SRV_ADDR "127.0.0.1"                                                 
  12. #define SRV_PORT 6500 
  13.  
  14. #include "client.h"                                                               
  15.                                                                                   
  16. using namespace std;                                                              
  17.                                                                                   
  18. char buffer[512];                                                                 
  19.                                                                                   
  20. int main(int argc, char *argv[])                                                  
  21. {                                                                                 
  22.     /* Create a UDP socket */                                                     
  23.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);                                  
  24.                                                                                   
  25.     /* Construct the address for use with sendto/recvfrom */                      
  26.     struct sockaddr_in address;                                                   
  27.     address.sin_family = AF_INET;                                                 
  28.     address.sin_addr.s_addr = inet_addr(SRV_ADDR);                                
  29.     address.sin_port = htons(SRV_PORT);                                           
  30.     int len = sizeof(address);                                                    
  31.                                                                                   
  32.     /* sendto */                                                                  
  33.     sendto(sockfd, buffer, sizeof(buffer), 0,                                     
  34.            (struct sockaddr *)&address, sizeof(address));                         
  35.                                                                                   
  36.     /* receive */                                                                 
  37.     recvfrom(sockfd, buffer, sizeof(buffer), 0,                                   
  38.              (struct sockaddr *)&address, (socklen_t *)&len);                     
  39.                                                                                   
  40.     /* debug */                                                                   
  41.     printf("RECV: %s", buffer);                                                   
  42.                                                                                   
  43.     /* close */                                                                   
  44.     close(sockfd);                                                                
  45.  
  46.     return 0;                                                                     

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章