Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
aptel
sockets3_concurrent_servers_polling_select
Commits
34595fa1
Commit
34595fa1
authored
Oct 05, 2016
by
DANIEL DIAZ SANCHEZ
Browse files
Upload new file
parent
0d839bec
Changes
1
Hide whitespace changes
Inline
Side-by-side
code/smart-select.c
0 → 100644
View file @
34595fa1
/* smart-select.c
*
* Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
* whole or in part in accordance to the General Public License (GPL).
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*****************************************************************************/
/*** smart-select.c ***/
/*** ***/
/*** The smart select combines preforking with the select() call to keep ***/
/*** the select descriptor arrays small. ***/
/*****************************************************************************/
#include
<stdio.h>
#include
<sys/socket.h>
#include
<resolv.h>
#include
<unistd.h>
#include
<signal.h>
#include
<sys/time.h>
#define MAXPROCESSES 5
#define MAXCONNECTIONS 2
int
NumChildren
=
0
;
/*---------------------------------------------------------------------*/
/*--- sig_child - SIGCHLD ---*/
/*---------------------------------------------------------------------*/
void
sig_child
(
int
signum
)
{
wait
(
0
);
NumChildren
--
;
}
/*---------------------------------------------------------------------*/
/*--- servlet - each servlet accepts a connection and keeps track ---*/
/*--- of it using a select() statement. ---*/
/*---------------------------------------------------------------------*/
void
servlet
(
int
server
)
{
fd_set
set
,
set_all
;
int
maxfd
=
server
;
int
ceiling
=
0
;
int
i
;
FD_ZERO
(
&
set
);
FD_ZERO
(
&
set_all
);
FD_SET
(
server
,
&
set_all
);
for
(;;)
{
struct
timeval
timeout
=
{
40
,
0
};
/* 40 seconds */
set
=
set_all
;
/*---Wait for some action---*/
if
(
select
(
maxfd
+
1
,
&
set
,
0
,
0
,
&
timeout
)
>
0
)
{
/*---If new connection, connect and add to list---*/
for
(
i
=
0
;
i
<
maxfd
+
1
;
i
++
)
{
if
(
FD_ISSET
(
i
,
&
set
)
)
{
if
(
i
==
server
)
{
if
(
ceiling
<
MAXCONNECTIONS
)
{
int
client
=
accept
(
server
,
0
,
0
);
if
(
maxfd
<
client
)
maxfd
=
client
;
FD_SET
(
client
,
&
set_all
);
ceiling
++
;
printf
(
"select process #%d: %d connected
\n
"
,
getpid
(),
ceiling
);
}
}
else
{
char
buffer
[
1024
];
int
bytes
;
bytes
=
recv
(
i
,
buffer
,
sizeof
(
buffer
),
0
);
write
(
0
,
buffer
,
bytes
);
if
(
bytes
==
0
)
{
close
(
i
);
FD_CLR
(
i
,
&
set_all
);
ceiling
--
;
printf
(
"select process #%d: %d connected
\n
"
,
getpid
(),
ceiling
);
}
else
/* process the request */
send
(
i
,
buffer
,
bytes
,
0
);
}
}
}
}
}
exit
(
0
);
}
/*---------------------------------------------------------------------*/
/*--- main - set up server and maintain the number of living servlets--*/
/*---------------------------------------------------------------------*/
int
main
(
int
count
,
char
*
strings
[])
{
int
sd
;
struct
sockaddr_in
addr
;
struct
sigaction
act
;
if
(
count
!=
2
)
{
printf
(
"usage: %s <port>
\n
"
,
strings
[
0
]);
exit
(
0
);
}
bzero
(
&
act
,
sizeof
(
act
));
act
.
sa_handler
=
sig_child
;
act
.
sa_flags
=
SA_NOCLDSTOP
|
SA_RESTART
;
if
(
sigaction
(
SIGCHLD
,
&
act
,
0
)
!=
0
)
perror
(
"sigaction()"
);
sd
=
socket
(
PF_INET
,
SOCK_STREAM
,
0
);
bzero
(
&
addr
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
atoi
(
strings
[
1
]));
addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
if
(
bind
(
sd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
0
)
{
listen
(
sd
,
15
);
for
(;;)
{
if
(
NumChildren
<
MAXPROCESSES
)
{
int
pid
;
if
(
(
pid
=
fork
())
==
0
)
servlet
(
sd
);
else
if
(
pid
>
0
)
NumChildren
++
;
else
perror
(
"fork()"
);
}
else
sleep
(
1
);
}
}
else
perror
(
"bind()"
);
return
0
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment