开源库实现对UDP协议的处理[作业]

0.UDP客户端

 1 /**
 2   udpclient.c
 3 */
 4 #include <stdio.h>
 5 #include <unistd.h>
 6 #include <sys/socket.h>
 7 #include <sys/types.h>
 8 #include <arpa/inet.h>
 9 #include <string.h>
10 #include <strings.h>
11 
12 #define PORT 8111
13 #define MSG_LEN 1024
14 
15 int main(int argc, char* argv[])
16 {
17     int  sockfd;
18     char send_buf[MSG_LEN] = { 0 };
19     char recv_buf[MSG_LEN + 1] = { 0 };
20     struct sockaddr_in serv_addr;
21 
22     if (argc != 2) {
23         printf("usage: udpclient <ip address>\n");
24         _exit(-1);
25     }
26 
27     bzero(&serv_addr, sizeof(serv_addr));
28     serv_addr.sin_family = AF_INET;
29     serv_addr.sin_port = htons(PORT);
30     inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
31     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
32 
33     while (gets(send_buf) != NULL) {
34         sendto(sockfd, 
35             send_buf, 
36             strlen(send_buf), 
37             0, 
38             (struct sockaddr *)&serv_addr, 
39             sizeof(serv_addr));
40         int n = recvfrom(sockfd, recv_buf, MSG_LEN, 0, NULL, NULL);
41         if (n > 0) {
42             recv_buf[n] = '\0';
43             printf("recv[%s|%d]\n", recv_buf, n);
44         }
45     }
46 
47     return 0;
48 }
49 
50 # gcc -g -o udpclient udpclient.c
51 # ./udpclient

 

1.使用libevent实现对UDP的处理

 1 /**
 2   event_udpserver.c
 3 */
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 #include <sys/types.h>
 9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #include <event.h>
13 #include <event2/listener.h>
14 
15 #define PORT 8111
16 #define MSG_LEN 1024
17 
18 void read_cb(int fd, short event, void *arg) {
19     char buf[MSG_LEN];
20     int len;
21     socklen_t addr_len = sizeof(struct sockaddr);
22     struct sockaddr_in cli_addr;
23 
24     memset(buf, 0, sizeof(buf));
25     len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cli_addr, &addr_len);
26 
27     if (len == -1) {
28         perror("recvfrom");
29     } else if (len == 0) {
30         printf("Connection Closed\n");
31     } else {
32         buf[len] = '\0';
33         printf("recv[%s:%d]\n", buf, len);
34         sendto(fd, buf, len, 0, (struct sockaddr *)&cli_addr, addr_len);
35     }
36 }
37 
38 int bind_socket(struct event *ev) {
39     int sock_fd;
40     int flag = 1;
41     struct sockaddr_in local_addr;
42 
43     if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
44         perror("socket");
45         return -1;
46     }
47 
48     if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0) {
49         perror("setsockopt");
50         return 1;
51     }
52 
53     memset(&local_addr, 0, sizeof(local_addr));
54     local_addr.sin_family = AF_INET;
55     local_addr.sin_port = htons(PORT);
56     local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
57     if (bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr)) < 0) {
58         perror("bind");
59         return -1;
60     } else {
61         printf("bind success, port[%d]\n", PORT);
62     }
63 
64     event_set(ev, sock_fd, EV_READ | EV_PERSIST, &read_cb, NULL);
65     if (event_add(ev, NULL) == -1) {
66         perror("event_set");
67     }
68 
69     return 0;
70 }
71 
72 int main() 
73 {
74     struct event ev;
75 
76     if (event_init() == NULL) {
77         perror("event_init");
78         _exit(-1);
79     }
80 
81     if (bind_socket(&ev) != 0) {
82         perror("bind_socket");
83         _exit(-1);
84     }
85 
86     event_dispatch();
87 
88     return 0;
89 }
90 
91 # gcc -std=c11 -g -o event_udpserver event_udpserver.c `pkg-config --libs --cflags libevent`
92 # ./event_udpserver

 

2.使用libuv实现对UDP的处理

 1 /**
 2   uv_udpserver.c
 3 */
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include <strings.h>
 8 #include <sys/types.h>
 9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <uv.h>
12 
13 #define PORT 8111
14 #define MSG_LEN 1024
15 
16 uv_loop_t* loop = NULL;
17 uv_udp_t serv_socket;
18 uv_udp_t cli_socket;
19 
20 void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
21 
22 void on_read(uv_udp_t* handle, ssize_t nread, 
23     const uv_buf_t* buf, const struct sockaddr * addr, unsigned flags);
24 
25 void on_send(uv_udp_send_t* req, int status);
26 
27 int main(int argc, char* argv[])
28 {
29     loop = uv_default_loop();
30 
31     struct sockaddr_in serv_addr;
32     uv_ip4_addr("0.0.0.0", PORT, &serv_addr);
33     uv_udp_init(loop, &serv_socket);
34     uv_udp_bind(&serv_socket, (struct sockaddr *)&serv_addr, UV_UDP_REUSEADDR);
35     uv_udp_recv_start(&serv_socket, alloc_buffer, on_read);
36 
37     uv_udp_init(loop, &cli_socket);
38 
39     return uv_run(loop, UV_RUN_DEFAULT);;
40 }
41 
42 void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
43 {
44     printf("alloc size[%d]\n", suggested_size);
45     buf->base = (char *)malloc(suggested_size);
46     buf->len = suggested_size;
47 }
48 
49 void on_read(uv_udp_t* handle, ssize_t nread, 
50     const uv_buf_t* buf, const struct sockaddr * addr, unsigned flags)
51 {
52     printf("on_read, nread[%d]\n", nread);
53     uv_udp_send_t* req = NULL;
54     if (nread == 0) {
55         return;
56     }
57 
58     req = malloc(sizeof(uv_udp_send_t));
59     if (req == NULL) {
60         return;    
61     }
62 
63     uv_buf_t send_buf = uv_buf_init(buf->base, nread);
64     uv_udp_send(req, handle, &send_buf, 1, addr, on_send);
65 
66     free(buf->base);
67 }
68 
69 void on_send(uv_udp_send_t* req, int status)
70 {
71     if (status != 0) {
72         fprintf(stderr, "uv_udp_send error:%s\n", uv_strerror(status));
73     }
74 }
75 
76 # gcc -std=c11 -g -o uv_udpserver uv_udpserver.c `pkg-config --libs --cflags libuv` -D_XOPEN_SOURCE=600
77 # ./uv_udpserver

 

posted @ 2020-06-26 23:18  sp0917  阅读(856)  评论(0编辑  收藏  举报