├── .github └── workflows │ └── c-cpp.yml ├── .gitignore ├── Makefile ├── README.md ├── driver.c ├── thread_socket.c └── thread_socket.h /.github/workflows/c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: make 17 | run: make 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | thread_socket 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -m64 -O3 -Wall -lpthread -fPIE -fstack-protector -Wno-incompatible-pointer-types 2 | 3 | thread_socket: 4 | clang $(CFLAGS) -o $(@) thread_socket.c driver.c 5 | 6 | clean: 7 | rm ./thread_socket 8 | 9 | install: 10 | cp -f ./thread_socket /usr/bin 11 | 12 | uninstall: 13 | rm -f /usr/bin/thread_socket 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 成品脚本 2 | [MLKit](https://github.com/sdk250/MLKit) 3 | # 介绍 4 | 这是一个`专门`用于百度直连的http轻量代理
5 | ~使用多线程编写,本身编译出来极为轻量~
6 | 更改程序执行逻辑,从 `多线程` 转至 `epoll多路复用` 。大幅度的降低了程序在高并发的情况下的内存占用 7 | 修改`用于连接的IP`在`thread_socket.h`中的宏定义`SERVER_ADDR`,将它修改为你想使用的百度直连IP,然后重新编译即可。
8 | 亦或者运行时加上 `-r` 参数来指定
9 | # Compile 10 | ```shell 11 | make 12 | ``` 13 | If it is not working, please try: 14 | ```shell 15 | clang -m64 -O3 -Wall -lpthread -o thread_socket thread_socket.c driver.c 16 | ``` 17 | # Usage 18 | ```shell 19 | ./thread_socket -h 20 | Usage of ./thread_socket: 21 | -p 22 | Set PORT while running 23 | -l Show running log 24 | -u 25 | Set UID while running 26 | -r 27 | Set IP of peer 28 | -d Start daemon service 29 | -h Show this message 30 | ``` 31 | 编译以后可以在任意终端上运行,比如安卓的Termux
32 | 使用的最直接的使用方法就是运行后在手机的APN设置里面设置代理:
33 | 127.0.0.1 端口 默认为8080 34 | # Email 35 | ` hexfya@gmail.com ` 36 | 37 | -------------------------------------------------------------------------------- /driver.c: -------------------------------------------------------------------------------- 1 | #include "thread_socket.h" 2 | 3 | void signal_terminate(const int sign) 4 | { 5 | atomic_store_explicit(&SHUTDOWN, true, memory_order_release); 6 | fprintf(stderr, "Receive terminated signal: %d\n", sign); 7 | close(local_fd); 8 | } 9 | 10 | void usage(const char *argv, const int ret) 11 | { 12 | printf("Usage of %s:\n" 13 | "\t-p\t\n" 14 | "\t\tSet PORT while running\n" 15 | "\t-u\t\n" 16 | "\t\tSet UID while running\n" 17 | "\t-r\t\n" 18 | "\t\tSet IP of peer\n" 19 | "\t-l\tShow running log\n" 20 | "\t-d\tStart daemon service\n" 21 | "\t-h\tShow this message\n", 22 | argv 23 | ); 24 | exit(ret); 25 | } 26 | 27 | void *handle_swap(void *arg) 28 | { 29 | int32_t epoll_fd = *(int32_t *) arg; 30 | char *buf = (char *) arg; 31 | memset(buf, '\0', sizeof(int32_t)); 32 | struct epoll_event events[MAX_EVENT]; 33 | 34 | for (int event_count = 0; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);) 35 | { 36 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1); 37 | for (int i = 0; i < event_count; i++) 38 | { 39 | if (events[i].events & EPOLLIN) 40 | { 41 | int32_t *src = (int32_t *) &events[i].data.u64; 42 | int32_t *dst = src + 1; 43 | bool _continue = false; 44 | 45 | int recved = 0; 46 | for (; 47 | (recved = recv(*src, buf, SIZE, 0)); 48 | ) 49 | { 50 | if (recved < 0) 51 | { 52 | _continue = (errno == EAGAIN || errno == EWOULDBLOCK); 53 | break; 54 | } 55 | send(*dst, buf, recved, MSG_NOSIGNAL); 56 | memset(buf, '\0', recved); 57 | } 58 | if (!_continue || recved == 0) 59 | { 60 | for (int i = 0; i < 2; i++) 61 | { 62 | if (*(src + i) != 0) 63 | { 64 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, *(src + i), NULL); 65 | close(*(src + i)); 66 | *(src + i) = 0; 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | pthread_exit(NULL); 74 | return NULL; 75 | } 76 | void *handle_server(void *arg) 77 | { 78 | int32_t epoll_fd = *(int32_t *) arg; 79 | int32_t swap_epoll_fd = *(((int32_t *) arg) + 1); 80 | char *buf = (char *) arg; 81 | memset(buf, '\0', sizeof(int64_t)); 82 | struct epoll_event event, events[MAX_EVENT]; 83 | 84 | for (int event_count = 0; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);) 85 | { 86 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1); 87 | for (int i = 0; i < event_count; i++) 88 | { 89 | struct server_argu *server_ptr = (struct server_argu *) events[i].data.ptr; 90 | int32_t src = server_ptr->src; 91 | int32_t dst = server_ptr->dst; 92 | 93 | if (events[i].events & EPOLLOUT) 94 | { 95 | send( 96 | dst, 97 | server_ptr->msg, 98 | strlen(server_ptr->msg), 99 | MSG_NOSIGNAL 100 | ); 101 | 102 | memset(&event, '\0', sizeof(struct epoll_event)); 103 | event.events = EPOLLIN | EPOLLET; 104 | event.data.ptr = events[i].data.ptr; 105 | events[i].data.ptr = NULL; 106 | epoll_ctl(epoll_fd, EPOLL_CTL_MOD, dst, &event); 107 | 108 | free(server_ptr->msg); 109 | server_ptr->msg = NULL; 110 | } else if (events[i].events & EPOLLIN) { 111 | for ( 112 | short int i = 0, end_i = 39; 113 | (i = recv(dst, buf, end_i, 0)) != end_i && i > 0; 114 | end_i -= i 115 | ) continue; 116 | if (! strstr(buf, "\r\n\r\n")) 117 | { 118 | memset(buf, '\0', 39); 119 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, dst, NULL); 120 | shutdown(dst, SHUT_RDWR); 121 | close(dst); 122 | close(src); 123 | free(server_ptr); 124 | continue; 125 | } 126 | 127 | if (server_ptr->http_msg == NULL) 128 | send( 129 | src, 130 | buf, 131 | 39, 132 | MSG_NOSIGNAL 133 | ); 134 | else { 135 | send( 136 | dst, 137 | server_ptr->http_msg, 138 | server_ptr->http_msg_len, 139 | MSG_NOSIGNAL 140 | ); 141 | free(server_ptr->http_msg); 142 | server_ptr->http_msg = NULL; 143 | } 144 | memset(buf, '\0', 39); 145 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, dst, NULL); 146 | free(server_ptr); 147 | events[i].data.ptr = NULL; 148 | 149 | define_event(swap_epoll_fd, &event, src, dst); 150 | define_event(swap_epoll_fd, &event, dst, src); 151 | } 152 | } 153 | } 154 | pthread_exit(NULL); 155 | return NULL; 156 | } 157 | inline void define_event( 158 | int32_t epoll_fd, 159 | struct epoll_event *event, 160 | int32_t src, 161 | int32_t dst 162 | ) 163 | { 164 | memset(event, '\0', sizeof(struct epoll_event)); 165 | *(int32_t *) &(event->data) = src; 166 | *(((int32_t *) &(event->data)) + 1) = dst; 167 | event->events = EPOLLIN | EPOLLET; 168 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, src, event); 169 | } 170 | void main_loop(const int local_fd) 171 | { 172 | int epoll_fd, event_count; 173 | struct epoll_event event, events[MAX_EVENT]; 174 | char *thread_buf_swap = calloc(SIZE, sizeof(char)); 175 | char *thread_buf_server = calloc(SIZE, sizeof(char)); 176 | char *buf = calloc(SIZE, sizeof(char)); 177 | char *_buf = calloc(SIZE, sizeof(char)); 178 | char *url = calloc(LEN_URL, sizeof(char)); 179 | if (! thread_buf_swap || ! buf || ! _buf || ! thread_buf_server || ! url) 180 | { 181 | perror("calloc"); 182 | exit(EXIT_FAILURE); 183 | } 184 | 185 | epoll_fd = epoll_create1(0); 186 | int32_t swap_epoll_fd = epoll_create1(0); 187 | int32_t server_epoll_fd = epoll_create1(0); 188 | *(int32_t *) thread_buf_swap = swap_epoll_fd; 189 | *(int32_t *) thread_buf_server = server_epoll_fd; 190 | *(((int32_t *) thread_buf_server) + 1) = swap_epoll_fd; 191 | pthread_t tid_swap, tid_server; 192 | pthread_create(&tid_swap, &attr, handle_swap, thread_buf_swap); 193 | pthread_create(&tid_server, &attr, handle_server, thread_buf_server); 194 | 195 | event.events = EPOLLIN; 196 | event.data.fd = local_fd; 197 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_fd, &event); 198 | for (; !atomic_load_explicit(&SHUTDOWN, memory_order_relaxed);) 199 | { 200 | event_count = epoll_wait(epoll_fd, events, MAX_EVENT, -1); 201 | for (int i = 0; i < event_count; i++) 202 | { 203 | int fd = events[i].data.fd; 204 | if (fd == local_fd) 205 | { 206 | int _fd = accept(fd, NULL, NULL); 207 | if (_fd < 0) 208 | continue; 209 | 210 | setNonBlocking(_fd); 211 | event.events = EPOLLIN | EPOLLET; 212 | event.data.fd = _fd; 213 | epoll_ctl(epoll_fd, EPOLL_CTL_ADD, _fd, &event); 214 | } else if (events[i].events & EPOLLIN) { 215 | int32_t total = 0, https = 0, dst = 0; 216 | struct sockaddr_in destination_addr; 217 | socklen_t len = sizeof(struct sockaddr); 218 | 219 | memset(&destination_addr, '\0', sizeof(struct sockaddr)); 220 | if (getsockopt( 221 | fd, 222 | SOL_IP, 223 | SO_ORIGINAL_DST, 224 | &destination_addr, 225 | &len 226 | ) != 0 || ( 227 | (ntohl(destination_addr.sin_addr.s_addr) == 0x0) || // 0.0.0.0/0 228 | (ntohl(destination_addr.sin_addr.s_addr) & 0xff000000) == 0x0a000000 || // 10.0.0.0/8 229 | (ntohl(destination_addr.sin_addr.s_addr) & 0xfff00000) == 0xac100000 || // 172.16.0.0/12 230 | (ntohl(destination_addr.sin_addr.s_addr) & 0xffff0000) == 0xc0a80000 || // 192.168.0.0/16 231 | (ntohl(destination_addr.sin_addr.s_addr) & 0xff000000) == 0x7f000000 || // 127.0.0.0/8 232 | (ntohl(destination_addr.sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000 || // 169.254.0.0/16 233 | (ntohl(destination_addr.sin_addr.s_addr) & 0xf0000000) == 0xe0000000 // 224.0.0.0/4 234 | )) { 235 | for (short int ret = 0; 236 | total + READ_SIZE < SIZE && 237 | ! strstr(buf, "\r\n\r\n") && 238 | (ret = recv(fd, buf + total, READ_SIZE, 0)); 239 | ) 240 | { 241 | if (ret == -1) 242 | break; 243 | else 244 | total += ret; 245 | } 246 | 247 | for (char *p = buf; (uintptr_t) p != 1 && p - buf < SIZE; p++) 248 | { 249 | if (sscanf(p, "Host: %" LEN_URL_STR "[^ \r\n]\r\n", url) == 1 || 250 | sscanf(p, "host: %" LEN_URL_STR "[^ \r\n]\r\n", url) == 1 251 | ) 252 | break; 253 | 254 | p = strchr(p, '\n'); 255 | } 256 | if (*url == 0) 257 | { 258 | if (sscanf(buf, "CONNECT %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) { 259 | if (sscanf(buf, "GET %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) { 260 | if (sscanf(buf, "POST %" LEN_URL_STR "[^ ] %*[^ ]\r\n", url) != 1) { 261 | if (LOG) fprintf(stderr, "Unknown connection.\n"); 262 | memset(buf, '\0', total); 263 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 264 | close(fd); 265 | continue; 266 | } 267 | } 268 | } 269 | } 270 | for (int i = 0; i < 8; i++) 271 | { 272 | if (buf[i] == "CONNECT "[i]) 273 | https = 1; 274 | else { 275 | https = 0; 276 | break; 277 | } 278 | } 279 | if (!strchr(url, ':')) 280 | { 281 | if (https) 282 | strncat(url, ":443", LEN_URL); 283 | else 284 | strncat(url, ":80", LEN_URL); 285 | } 286 | } else { 287 | if (! inet_ntop(AF_INET, &destination_addr.sin_addr, url, INET_ADDRSTRLEN)) 288 | { 289 | perror("Translation fail"); 290 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 291 | close(fd); 292 | continue; 293 | } 294 | size_t len = strlen(url); 295 | if (len + 7 > LEN_URL) 296 | { 297 | fprintf(stderr, "URI is too long: %s\n", url); 298 | memset(url, '\0', len); 299 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 300 | close(fd); 301 | continue; 302 | } 303 | snprintf( 304 | url + len, 305 | LEN_URL, 306 | ":%u", 307 | ntohs(destination_addr.sin_port) 308 | ); 309 | } 310 | 311 | if (LOG) printf("url: %s\n", url); 312 | 313 | if ((dst = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 314 | { 315 | perror("Create socket for zl"); 316 | memset(buf, '\0', total); 317 | memset(url, '\0', strlen(url)); 318 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 319 | close(fd); 320 | continue; 321 | } 322 | setNonBlocking(dst); 323 | set_socket_timeout(dst, 0, TIMEOUT); 324 | 325 | if (connect( 326 | dst, 327 | (struct sockaddr *) &server_addr, 328 | sizeof(struct sockaddr)) == -1 && errno != EINPROGRESS 329 | ) { 330 | perror("Connect to server fail"); 331 | close(dst); 332 | memset(buf, '\0', total); 333 | memset(url, '\0', strlen(url)); 334 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 335 | close(fd); 336 | continue; 337 | } 338 | snprintf( 339 | _buf, 340 | SIZE, 341 | "CONNECT %s HTTP/1.1\r\n\r\n", 342 | url 343 | ); 344 | memset(&event, '\0', sizeof(struct epoll_event)); 345 | event.events = EPOLLOUT | EPOLLET; 346 | event.data.ptr = calloc(1, sizeof(struct server_argu)); 347 | if (event.data.ptr == NULL) 348 | { 349 | perror("calloc"); 350 | close(dst); 351 | memset(buf, '\0', total); 352 | memset(_buf, '\0', strlen(_buf)); 353 | memset(url, '\0', strlen(url)); 354 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 355 | close(fd); 356 | continue; 357 | } 358 | ((struct server_argu *) event.data.ptr)->src = fd; 359 | ((struct server_argu *) event.data.ptr)->dst = dst; 360 | ((struct server_argu *) event.data.ptr)->msg = strdup(_buf); 361 | if (!https) 362 | { 363 | ((struct server_argu *) event.data.ptr)->http_msg = calloc(total + 1, sizeof(char)); 364 | if (((struct server_argu *) event.data.ptr)->http_msg == NULL) 365 | { 366 | perror("calloc"); 367 | close(dst); 368 | memset(buf, '\0', total); 369 | memset(_buf, '\0', strlen(_buf)); 370 | memset(url, '\0', strlen(url)); 371 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 372 | close(fd); 373 | continue; 374 | } 375 | memcpy(((struct server_argu *) event.data.ptr)->http_msg, buf, total); 376 | ((struct server_argu *) event.data.ptr)->http_msg_len = total; 377 | } 378 | epoll_ctl(server_epoll_fd, EPOLL_CTL_ADD, dst, &event); 379 | 380 | memset(buf, '\0', total); 381 | memset(_buf, '\0', strlen(_buf)); 382 | memset(url, '\0', strlen(url)); 383 | epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 384 | } 385 | } 386 | } 387 | 388 | close(epoll_fd); 389 | pthread_join(tid_swap, NULL); 390 | pthread_join(tid_server, NULL); 391 | close(swap_epoll_fd); 392 | close(server_epoll_fd); 393 | free(thread_buf_swap); 394 | free(thread_buf_server); 395 | free(buf); 396 | free(_buf); 397 | free(url); 398 | pthread_attr_destroy(&attr); 399 | 400 | puts("Main thread terminated."); 401 | } 402 | 403 | void set_socket_timeout(int fd, unsigned long int usec, unsigned int sec) 404 | { 405 | struct timeval tv = { 406 | .tv_usec = usec, 407 | .tv_sec = sec 408 | }; 409 | setsockopt( 410 | fd, 411 | SOL_SOCKET, 412 | SO_SNDTIMEO, 413 | (void *) &tv, 414 | sizeof(struct timeval) 415 | ); 416 | setsockopt( 417 | fd, 418 | SOL_SOCKET, 419 | SO_RCVTIMEO, 420 | (void *) &tv, 421 | sizeof(struct timeval) 422 | ); 423 | } 424 | int setNonBlocking(int sockfd) 425 | { 426 | int flags = fcntl(sockfd, F_GETFL, 0); 427 | if (flags == -1) { 428 | perror("fcntl"); 429 | return -1; 430 | } 431 | 432 | flags |= O_NONBLOCK; 433 | if (fcntl(sockfd, F_SETFL, flags) == -1) { 434 | perror("fcntl"); 435 | return -1; 436 | } 437 | 438 | return 0; 439 | } 440 | -------------------------------------------------------------------------------- /thread_socket.c: -------------------------------------------------------------------------------- 1 | #include "thread_socket.h" 2 | 3 | pthread_attr_t attr = {0}; 4 | int LOG = 0; 5 | int local_fd = 0; 6 | struct sockaddr_in server_addr = {0}; 7 | atomic_bool SHUTDOWN = false; 8 | 9 | int main(int argc, char **argv) { 10 | struct sockaddr_in local_addr = {0}; 11 | int on = 1; 12 | int opt = 0; 13 | int daemon = 0; 14 | unsigned int port = 8080; 15 | pid_t pid = 0; 16 | pid_t sid = 0; 17 | char ip_s[16] = {0}; 18 | 19 | if (argc == 1) 20 | usage(*argv, EXIT_FAILURE); 21 | for (;(opt = getopt(argc, argv, "p:u:r:dlh")) != -1;) { 22 | switch(opt) { 23 | case 'p': 24 | port = atoi(optarg); 25 | break; 26 | case 'd': 27 | daemon = 1; 28 | break; 29 | case 'l': 30 | LOG = 1; 31 | break; 32 | case 'u': 33 | if (setuid(atoi(optarg))) 34 | perror("Setuid error"); 35 | break; 36 | case 'r': 37 | strncpy(ip_s, optarg, 15); 38 | break; 39 | case 'h': 40 | usage(*argv, EXIT_SUCCESS); 41 | break; 42 | case ':': 43 | printf("Missing argument after: -%c\n", optopt); 44 | usage(*argv, EXIT_FAILURE); 45 | break; 46 | case '?': 47 | printf("Invalid argument: -%c\n", optopt); 48 | usage(*argv, EXIT_FAILURE); 49 | default: 50 | usage(*argv, EXIT_FAILURE); 51 | } 52 | } 53 | 54 | if (*ip_s == '\0') 55 | strncpy(ip_s, SERVER_ADDR, 15); 56 | 57 | memset(&server_addr, '\0', sizeof(struct sockaddr)); 58 | server_addr.sin_family = AF_INET; 59 | server_addr.sin_port = htons(443); 60 | if (inet_pton(AF_INET, ip_s, &server_addr.sin_addr) != 1) 61 | { 62 | perror("Translation address failed"); 63 | exit(EXIT_FAILURE); 64 | } 65 | 66 | signal(SIGPIPE, SIG_IGN); 67 | signal(SIGALRM, SIG_IGN); 68 | signal(SIGINT, signal_terminate); 69 | signal(SIGTERM, signal_terminate); 70 | if ((local_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 71 | perror("Create local server socket file descriptor fail"); 72 | close(local_fd); 73 | exit(EXIT_FAILURE); 74 | } 75 | setsockopt(local_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 76 | memset(&local_addr, '\0', sizeof(struct sockaddr)); 77 | local_addr.sin_family = AF_INET; 78 | local_addr.sin_port = htons(port); 79 | local_addr.sin_addr.s_addr = INADDR_ANY; 80 | if (bind( 81 | local_fd, 82 | (const struct sockaddr *) &local_addr, 83 | sizeof(struct sockaddr) 84 | ) < 0) { 85 | fprintf( 86 | stderr, 87 | "Bind %s:%u error", 88 | inet_ntoa(local_addr.sin_addr), 89 | port 90 | ); 91 | perror(" "); 92 | close(local_fd); 93 | exit(EXIT_FAILURE); 94 | } 95 | if (listen(local_fd, 50) < 0) { 96 | perror("listen"); 97 | close(local_fd); 98 | exit(EXIT_FAILURE); 99 | } 100 | setNonBlocking(local_fd); 101 | printf( 102 | __TIME__ "\t" __DATE__ "\n" 103 | "Listen on %s:%u.\n", 104 | inet_ntoa(local_addr.sin_addr), 105 | port 106 | ); 107 | pthread_attr_init(&attr); 108 | pthread_attr_setstacksize(&attr, 512 * 1024); 109 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 110 | if (daemon) { 111 | if ((pid = fork()) == 0) { 112 | if ((sid = setsid()) < 0) { 113 | perror("setsid error"); 114 | exit(EXIT_FAILURE); 115 | } 116 | close(STDIN_FILENO); 117 | close(STDOUT_FILENO); 118 | // close(STDERR_FILENO); 119 | main_loop(local_fd); 120 | } else { 121 | printf("The PID of %s is %d.\n", *argv, pid); 122 | close(local_fd); 123 | } 124 | } else 125 | main_loop(local_fd); 126 | 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /thread_socket.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_SOCKET__ 2 | #define __THREAD_SOCKET__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #define SIZE 0x80000 20 | #define LEN_URL (SIZE / 2) 21 | #define LEN_URL_STR "262143" // LEN_URL - 1 22 | #define U_TIMEOUT 500000 23 | #define TIMEOUT 3 24 | #define SERVER_ADDR "110.242.70.68" 25 | #define READ_SIZE 0x100 26 | #define MAX_EVENT (64) 27 | 28 | extern pthread_attr_t attr; 29 | extern int LOG; 30 | extern int local_fd; 31 | extern struct sockaddr_in server_addr; 32 | extern atomic_bool SHUTDOWN; 33 | 34 | struct server_argu 35 | { 36 | int32_t src; 37 | int32_t dst; 38 | char *msg; 39 | char *http_msg; 40 | uint32_t http_msg_len; 41 | }; 42 | 43 | int setNonBlocking(int); 44 | void set_socket_timeout(int, unsigned long int, unsigned int); 45 | void *swap_data(void *); 46 | void main_loop(int); 47 | void usage(const char *, int); 48 | void signal_terminate(int); 49 | void *handle_server(void *); 50 | void *handle_swap(void *); 51 | extern inline void define_event( 52 | int32_t epoll_fd, 53 | struct epoll_event *event, 54 | int32_t src, 55 | int32_t dst 56 | ); 57 | 58 | #endif 59 | --------------------------------------------------------------------------------