环境:Linux
语言:C++
通信方式:UDP
服务器端的步骤如下:
1. socket: 建立一个socket
2. bind: 将这个socket绑定在某个端口上(AF_INET)
3. recvfrom: 如果没有客户端发起请求,则会阻塞在这个函数里
4. close: 通信完成后关闭socket
客户端的步骤如下:
1. socket: 建立一个socket
2. sendto: 相服务器的某个端口发起请求(AF_INET)
3. close: 通信完成后关闭socket
基于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 11 #define SERV_PORT 8000 12 13 14 int main() 15 { 16 /* socket文件描述符 */ 17 int sock_fd; //创建套接字 18 19 /* 建立udp socket */ 20 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 21 if(sock_fd < 0) 22 { 23 perror("socket"); 24 exit(1); 25 } 26 27 /* 将套接字和IP、端口绑定 */ 28 struct sockaddr_in addr_serv; 29 int len; 30 memset(&addr_serv, 0, sizeof(struct sockaddr_in)); //每个字节都用0填充 31 addr_serv.sin_family = AF_INET; //使用IPV4地址 32 addr_serv.sin_port = htons(SERV_PORT); //端口 33 /* INADDR_ANY表示不管是哪个网卡接收到数据,只要目的端口是SERV_PORT,就会被该应用程序接收到 */ 34 addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); //自动获取IP地址 35 len = sizeof(addr_serv); 36 37 /* 绑定socket */ 38 if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0) 39 { 40 perror("bind error:"); 41 exit(1); 42 } 43 44 45 int recv_num; 46 int send_num; 47 char send_buf[20] = "i am server!"; 48 char recv_buf[20]; 49 struct sockaddr_in addr_client; 50 51 while(1) 52 { 53 printf("server wait:\n"); 54 55 recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len); 56 57 if(recv_num < 0) 58 { 59 perror("recvfrom error:"); 60 exit(1); 61 } 62 63 recv_buf[recv_num] = '\0'; 64 printf("server receive %d bytes: %s\n", recv_num, recv_buf); 65 66 send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len); 67 68 if(send_num < 0) 69 { 70 perror("sendto error:"); 71 exit(1); 72 } 73 } 74 75 close(sock_fd); 76 77 return 0; 78 }
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