LinuxCC++UDPSocket通信实例环境:Linux
语⾔:C/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#define SERV_PORT 8000
11
12int main()
13 {
14/* sock_fd --- socket⽂件描述符创建udp套接字*/
15int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
16if(sock_fd < 0)
17 {
18 perror("socket");
19 exit(1);
20 }
21
22/* 将套接字和IP、端⼝绑定 */
23struct sockaddr_in addr_serv;
24int 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 */
33if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
34 {
35 perror("bind error:");
36 exit(1);
37 }
38
39
40int recv_num;
41int send_num;
42char send_buf[20] = "i am server!";
43char recv_buf[20];
44struct sockaddr_in addr_client;
45
46while(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
52if(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
63if(send_num < 0)
64 {
65 perror("sendto error:");
66 exit(1);
67 }
68 }
69
70 close(sock_fd);
71
72return0;
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
16int main()
17 {
18/* socket⽂件描述符 */
19int sock_fd;
20
21/* 建⽴udp socket */
22 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
23if(sock_fd < 0)
24 {
25 perror("socket");
26 exit(1);
27 }
28
29/* 设置address */
30struct sockaddr_in addr_serv;
31int 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
39int send_num;
socket通信为什么要指定端口40int recv_num;
41char send_buf[20] = "hey, who are you?";
42char 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
48if(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
56if(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
67return0;
68 }
程序运⾏截图:
client向服务器发送了“hey, who are you?”的字符串,server返回"i am server!"的字符串。
参考链接:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论