#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define PORT 5555
#define MAXMSG 512
int
make_socket (uint16_t port)
{
int server_sock;
struct sockaddr_in name;
int yes = 1;
/* Create the socket. */
server_sock = socket (PF_INET, SOCK_STREAM, 0);
if (server_sock < 0)
{
perror ("socket");
exit (EXIT_FAILURE);
}
// tento radek zpusobi, ze pri opakovanem restartu serveru, bude volani
// funkce bind() uspesne, kdo neveri, at ho zakomentuje :))
if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
perror("setsockopt");
exit(1);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (server_sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
perror ("bind");
exit (EXIT_FAILURE);
}
return server_sock;
}
int read_from_client (int filedes)
{
char buffer[MAXMSG];
int nbytes;
nbytes = read (filedes, buffer, MAXMSG);
if (nbytes < 0)
{
/* Read error. */
perror ("read");
exit (EXIT_FAILURE);
}
else if (nbytes == 0)
/* End-of-file. */
return -1;
else
{
/* Data read. */
fprintf (stderr, "Server: got message: `%s'\n", buffer);
return 0;
}
}
int
main (void)
{
int server_sock;
fd_set active_fd_set, read_fd_set;
int fd;
struct sockaddr_in clientname;
size_t size;
/* Create the socket and set it up to accept connections. */
server_sock = make_socket (PORT);
if (listen (server_sock, 1) < 0)
{
perror ("listen");
exit (EXIT_FAILURE);
}
/* Initialize the set of active sockets. */
FD_ZERO (&active_fd_set);
FD_SET (server_sock, &active_fd_set);
while (1)
{
/* Block until input arrives on one or more active sockets. */
read_fd_set = active_fd_set;
if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
{
perror ("select");
exit (EXIT_FAILURE);
}
/* Service all the sockets with input pending. */
for (fd = 0; fd < FD_SETSIZE; ++fd)
if (FD_ISSET (fd, &read_fd_set))
{
if (fd == server_sock)
{
/* Connection request on original socket. */
int new;
size = sizeof (clientname);
new = accept (server_sock,
(struct sockaddr *) &clientname,
&size);
if (new < 0)
{
perror ("accept");
exit (EXIT_FAILURE);
}
fprintf (stderr,
"Server: connect from host %s, port %hd.\n",
inet_ntoa (clientname.sin_addr),
ntohs (clientname.sin_port));
FD_SET (new, &active_fd_set); /* Add new client to the set */
}
else
{
/* Data arriving on an already-connected socket. */
if (read_from_client (fd) < 0)
{
/* Client closed the connection */
FD_CLR (fd, &active_fd_set); /* Remove the client from the set */
close (fd);
}
}
}
}
}