Linux C/C++ UDP Socket通訊實例

環境:Linuxhtml

語言:C/C++服務器

通訊方式:UDPsocket

服務器端的步驟以下:

1. socket:      創建一個socket函數

2. bind:          將這個socket綁定在某個端口上(AF_INET)spa

3. recvfrom:  若是沒有客戶端發起請求,則會阻塞在這個函數裏.net

4. close:        通訊完成後關閉socketcode

客戶端的步驟以下:

1. socket:      創建一個socketserver

2. sendto:     向服務器的某個端口發起請求(AF_INET)htm

3. close:        通訊完成後關閉socketblog

 

基於UDP的接收和發送函數

int recvfrom(int sockfd, void * buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen);

int sendto(int sockfd, const void * buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen);

UDP套接字不會保持鏈接狀態,每次傳輸數據都要添加目標地址信息,這至關於在郵寄包裹前填寫收件人地址。

 

recvfrom用於接收數據,sendto用於發送數據

recvfrom:

  • sockfd:用於接收UDP數據的套接字;
  • buf:保存接收數據的緩衝區地址;
  • len:可接收的最大字節數(不能超過buf緩衝區的大小);
  • flags:可選項參數,若沒有可傳遞0;
  • src_addr:存有發送端地址信息的sockaddr結構體變量的地址;
  • addrlen:保存參數 src_addr的結構體變量長度的變量地址值。

sendto:

  • sockfd:用於傳輸UDP數據的套接字;
  • buf:保存待傳輸數據的緩衝區地址;
  • len:帶傳輸數據的長度(以字節計);
  • flags:可選項參數,若沒有可傳遞0;
  • dest_addr:存有目標地址信息的 sockaddr 結構體變量的地址;
  • addrlen:傳遞給參數 dest_addr的地址值結構體變量的長度。

 

Server.cpp

 1 #include <stdio.h>   
 2 #include <sys/types.h>   
 3 #include <sys/socket.h>   
 4 #include <netinet/in.h>   
 5 #include <unistd.h>   
 6 #include <errno.h>   
 7 #include <string.h>   
 8 #include <stdlib.h>   
 9   
10 #define SERV_PORT   8000   
11   
12 int main() 13 { 14   /* sock_fd --- socket文件描述符 建立udp套接字*/  
15   int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 16   if(sock_fd < 0) 17  { 18     perror("socket"); 19     exit(1); 20  } 21   
22   /* 將套接字和IP、端口綁定 */  
23   struct sockaddr_in addr_serv; 24   int len; 25   memset(&addr_serv, 0, sizeof(struct sockaddr_in));  //每一個字節都用0填充
26   addr_serv.sin_family = AF_INET;              //使用IPV4地址
27   addr_serv.sin_port = htons(SERV_PORT);          //端口
28   /* INADDR_ANY表示無論是哪一個網卡接收到數據,只要目的端口是SERV_PORT,就會被該應用程序接收到 */  
29   addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  //自動獲取IP地址
30   len = sizeof(addr_serv); 31     
32   /* 綁定socket */  
33   if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0) 34  { 35     perror("bind error:"); 36     exit(1); 37  } 38   
39     
40   int recv_num; 41   int send_num; 42   char send_buf[20] = "i am server!"; 43   char recv_buf[20]; 44   struct sockaddr_in addr_client; 45   
46   while(1) 47  { 48     printf("server wait:\n"); 49       
50     recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len); 51       
52     if(recv_num < 0) 53  { 54       perror("recvfrom error:"); 55       exit(1); 56  } 57   
58     recv_buf[recv_num] = '\0'; 59     printf("server receive %d bytes: %s\n", recv_num, recv_buf); 60   
61     send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len); 62       
63     if(send_num < 0) 64  { 65       perror("sendto error:"); 66       exit(1); 67  } 68  } 69     
70  close(sock_fd); 71     
72   return 0; 73 }

Client.cpp

 1 #include <stdio.h>   
 2 #include <string.h>   
 3 #include <errno.h>   
 4 #include <stdlib.h>   
 5 #include <unistd.h>   
 6 #include <sys/types.h>   
 7 #include <sys/socket.h>   
 8 #include <netinet/in.h>   
 9 #include <arpa/inet.h>   
10    
11   
12 #define DEST_PORT 8000   
13 #define DSET_IP_ADDRESS  "127.0.0.1"   
14    
15   
16 int main() 17 { 18   /* socket文件描述符 */  
19   int sock_fd; 20   
21   /* 創建udp socket */  
22   sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 23   if(sock_fd < 0) 24  { 25     perror("socket"); 26     exit(1); 27  } 28     
29   /* 設置address */  
30   struct sockaddr_in addr_serv; 31   int len; 32   memset(&addr_serv, 0, sizeof(addr_serv)); 33   addr_serv.sin_family = AF_INET; 34   addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS); 35   addr_serv.sin_port = htons(DEST_PORT); 36   len = sizeof(addr_serv); 37   
38     
39   int send_num; 40   int recv_num; 41   char send_buf[20] = "hey, who are you?"; 42   char recv_buf[20]; 43       
44   printf("client send: %s\n", send_buf); 45     
46   send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len); 47     
48   if(send_num < 0) 49  { 50     perror("sendto error:"); 51     exit(1); 52  } 53     
54   recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len); 55     
56   if(recv_num < 0) 57  { 58     perror("recvfrom error:"); 59     exit(1); 60  } 61     
62   recv_buf[recv_num] = '\0'; 63   printf("client receive %d bytes: %s\n", recv_num, recv_buf); 64     
65  close(sock_fd); 66     
67   return 0; 68 }

 程序運行截圖:

client向服務器發送了「hey, who are you?」的字符串,server返回"i am server!"的字符串。

 

參考連接:

https://blog.csdn.net/imxiangzi/article/details/45689709

http://c.biancheng.net/cpp/html/3052.html

相關文章
相關標籤/搜索