开源库实现对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