• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <arpa/inet.h>
17 #include <assert.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <netinet/in.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/epoll.h>
26 #include <sys/resource.h>
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 
33 #define MAXBUF       1024
34 #define MAXEPOLLSIZE 100
35 
setnonblocking(int sockfd)36 int setnonblocking(int sockfd)
37 {
38     return fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
39 }
40 
pthread_handle_message(void * sock_fd)41 void *pthread_handle_message(void *sock_fd)
42 {
43     char recvbuf[MAXBUF + 1];
44     char sendbuf[MAXBUF + 1];
45     int ret;
46     int new_fd;
47     struct sockaddr_in client_addr;
48     socklen_t cli_len = sizeof(client_addr);
49     int *sock_fd_new = (int *)sock_fd;
50     new_fd = *sock_fd_new;
51 
52     bzero(recvbuf, MAXBUF + 1);
53     bzero(sendbuf, MAXBUF + 1);
54 
55     do {
56         ret = recvfrom(new_fd, recvbuf, MAXBUF, 0, (struct sockaddr *)&client_addr, &cli_len);
57         if (ret > 0) {
58             printf("socket %d recv from :%s:%d success.msg=[%s]total %d bytes\n", new_fd,
59                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recvbuf, ret);
60         } else {
61             printf("rece msg failed.ret=%d,error code=%d,error msg=%s\n", ret, errno, strerror(errno));
62         }
63     } while (ret > 0);
64 
65     fflush(stdout);
66     pthread_exit(NULL);
67 }
68 
main(int argc,char ** argv)69 int main(int argc, char **argv)
70 {
71     int listener, kdpfd, nfds, n;
72     socklen_t len;
73     struct sockaddr_in my_addr;
74     unsigned int myport;
75     struct epoll_event ev;
76     struct epoll_event events[MAXEPOLLSIZE];
77     struct rlimit rt;
78 
79     myport = 9999;
80 
81     pthread_t thread;
82     pthread_attr_t attr;
83 
84     rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
85     if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {
86         perror("setrlimit");
87         exit(1);
88     } else {
89         printf("set param success\n");
90     }
91 
92     if ((listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
93         perror("socket create failed.\n");
94         exit(1);
95     } else {
96         printf("socket create success\n");
97     }
98 
99     int opt = SO_REUSEADDR;
100     setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
101 
102     setnonblocking(listener);
103     bzero(&my_addr, sizeof(my_addr));
104     my_addr.sin_family = PF_INET;
105     my_addr.sin_port = htons(myport);
106     my_addr.sin_addr.s_addr = INADDR_ANY;
107     if (bind(listener, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
108         perror("bind");
109         exit(1);
110     } else {
111         printf("IP bind success\n");
112     }
113 
114     kdpfd = epoll_create(MAXEPOLLSIZE);
115     len = sizeof(struct sockaddr_in);
116     ev.events = EPOLLIN | EPOLLET;
117     ev.data.fd = listener;
118     if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0) {
119         fprintf(stderr, "epoll set insertion error: fd=%d\n", listener);
120         return -1;
121     } else {
122         printf("epoll add success\n");
123     }
124 
125     while (1) {
126         nfds = epoll_wait(kdpfd, events, 10000, -1);
127         if (nfds == -1) {
128             perror("epoll_wait");
129             break;
130         }
131 
132         for (n = 0; n < nfds; ++n) {
133             if (events[n].data.fd == listener) {
134                 pthread_attr_init(&attr);
135                 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
136 
137                 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
138 
139                 if (pthread_create(&thread, &attr, pthread_handle_message, (void *)&(events[n].data.fd))) {
140                     perror("pthread_creat error!");
141                     exit(-1);
142                 }
143             }
144         }
145     }
146     close(listener);
147     return 0;
148 }