|
ru.unix.bsd- RU.UNIX.BSD ------------------------------------------------------------------ From : Vadim Goncharov 2:5020/400 22 Oct 2005 04:35:05 To : Valentin Davydov Subject : Re: discard server -------------------------------------------------------------------------------- Hi Valentin Davydov! On Fri, 21 Oct 2005 11:05:57 +0000 (UTC); Valentin Davydov wrote about 'Re: discard server': VD> Спасибо всем за интересное обсуждение, задача решена. Была написана такая VD> программа: VD> #include <stdio.h> VD> #include <sys/types.h> VD> #include <unistd.h> VD> #include <sys/uio.h> VD> #include <sys/pipe.h> VD> main(){ VD> unsigned char buffer[PAGE_SIZE]; while(read(STDIN_FILENO,buffer,sizeof(buffer))>> 0); VD> }, VD> а в портах нашёлся onenetd (у которого, обращаю внимание, в selectе VD> последним аргументом стоит NULL, а не отфонарное число, лишённое VD> физсмысла). Из этих двух частей был собран сабж, способный одновременно VD> держать десятки тысяч соединений. Вот патч на мою прогу - теперь она форкается на каждую ~тысячу клиентов. Имхо, будет работать лучше, чем тысячи процессов, попробуй. Последний аргумент select() можешь заменить если хочешь - но он влиять не должен. - --- discard.c Tue Oct 18 02:41:07 2005 +++ discard1.c Sat Oct 22 07:22:54 2005 @@ -24,6 +24,7 @@ /* Global vars */ unsigned int listening_port; /* Port on which we listen for connections */ int listening_socket; /* Socket for incoming connections from clients */ +int nclients; /* number of currently active clients */ BYTE debug; /* 1 for debug mode, else 0 */ int max_sockets; /* max number of clients we can serve */ BYTE quit; /* 1 if time to break endless loop and quit */ @@ -35,15 +36,17 @@ quit = 1; } -void quit_program(void) +void clear_clients(void) { int i; - close(listening_socket); - for (i=0; i < max_sockets; i++) - if (FD_ISSET(i, &mainset)) - shutdown(i, SHUT_RDWR); + if ((FD_ISSET(i, &mainset)) && (i != listening_socket)) { + close(i); + FD_CLR(i, &mainset); + } + + nclients = 0; } void init_sig(void) @@ -173,7 +176,11 @@ looping = 0; /* close client and forget about it */ FD_CLR(fd, &mainset); - shutdown(fd, SHUT_RDWR); + close(fd); + nclients--; + /* if non-listening child, die after all clients exit */ + if ((nclients == 0) && (listening_socket == -1)) + quit = 1; } } } @@ -183,6 +190,7 @@ struct sockaddr_in client; int clilen; int yes = 1; + int pid; fd_set fds; struct timeval tv; int i, nfds, maxfd; @@ -253,8 +261,26 @@ /* new user accepted */ FD_SET(i, &mainset); + nclients++; if (debug) printf("New client connected, fd=%d\n", i); + + /* fork if needed */ + if (nclients > max_sockets - 4) { + pid = fork(); + if (pid < 0) { + /* ignore fork error */ + } + if (pid > 0) { + /* parent clears clents - they're now served by child */ + clear_clients(); + } else { + /* child no longer listens */ + FD_CLR(listening_socket, &mainset); + close(listening_socket); + listening_socket = -1; + } + } } check_input: @@ -285,6 +311,7 @@ listening_socket = -1; debug = 0; quit = 0; + nclients = 0; FD_ZERO(&mainset); /* prepare server */ @@ -342,7 +369,7 @@ } if (debug) { - printf("Discrad server is up and running in debug mode\n"); + printf("Discard server is up and running in debug mode\n"); } /* Main server I/O loop. */ @@ -350,6 +377,8 @@ { get_socket_action(); } - quit_program(); + clear_clients(); + if (listening_socket != -1) + close(listening_socket); return 0; } -- WBR, Vadim Goncharov. ICQ#166852181 mailto:vadim_nuclight@mail.ru [Moderator of RU.ANTI-ECOLOGY][FreeBSD][http://antigreen.org][LJ:/nuclight] --- slrn/0.9.8.1 on FreeBSD 4.11/i386 * Origin: Nuclear Lightning @ Tomsk, TPU AVTF Hostel (2:5020/400@fidonet) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.unix.bsd/10359bc23bdd7.html, оценка из 5, голосов 10
|