]>
Commit | Line | Data |
---|---|---|
28f540f4 RM |
1 | #include <stdio.h> |
2 | #include <errno.h> | |
3 | #include <stdlib.h> | |
4 | #include <unistd.h> | |
5 | #include <sys/types.h> | |
6 | #include <sys/socket.h> | |
7 | #include <netinet/in.h> | |
8 | #include <netdb.h> | |
9 | ||
10 | #define PORT 5555 | |
11 | #define MAXMSG 512 | |
12 | ||
13 | int | |
14 | read_from_client (int filedes) | |
15 | { | |
16 | char buffer[MAXMSG]; | |
17 | int nbytes; | |
18 | ||
19 | nbytes = read (filedes, buffer, MAXMSG); | |
20 | if (nbytes < 0) | |
21 | { | |
22 | /* Read error. */ | |
23 | perror ("read"); | |
24 | exit (EXIT_FAILURE); | |
25 | } | |
26 | else if (nbytes == 0) | |
27 | /* End-of-file. */ | |
28 | return -1; | |
29 | else | |
30 | { | |
31 | /* Data read. */ | |
32 | fprintf (stderr, "Server: got message: `%s'\n", buffer); | |
33 | return 0; | |
34 | } | |
35 | } | |
36 | ||
37 | int | |
38 | main (void) | |
39 | { | |
40 | extern int make_socket (unsigned short int port); | |
41 | int sock; | |
42 | fd_set active_fd_set, read_fd_set; | |
43 | int i; | |
44 | struct sockaddr_in clientname; | |
45 | size_t size; | |
46 | ||
47 | /* Create the socket and set it up to accept connections. */ | |
48 | sock = make_socket (PORT); | |
49 | if (listen (sock, 1) < 0) | |
50 | { | |
51 | perror ("listen"); | |
52 | exit (EXIT_FAILURE); | |
53 | } | |
54 | ||
55 | /* Initialize the set of active sockets. */ | |
56 | FD_ZERO (&active_fd_set); | |
57 | FD_SET (sock, &active_fd_set); | |
58 | ||
59 | while (1) | |
60 | { | |
61 | /* Block until input arrives on one or more active sockets. */ | |
62 | read_fd_set = active_fd_set; | |
63 | if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) | |
64 | { | |
65 | perror ("select"); | |
66 | exit (EXIT_FAILURE); | |
67 | } | |
68 | ||
69 | /* Service all the sockets with input pending. */ | |
70 | for (i = 0; i < FD_SETSIZE; ++i) | |
71 | if (FD_ISSET (i, &read_fd_set)) | |
72 | { | |
73 | if (i == sock) | |
74 | { | |
75 | /* Connection request on original socket. */ | |
76 | int new; | |
77 | size = sizeof (clientname); | |
78 | new = accept (sock, | |
79 | (struct sockaddr *) &clientname, | |
80 | &size); | |
81 | if (new < 0) | |
82 | { | |
83 | perror ("accept"); | |
84 | exit (EXIT_FAILURE); | |
85 | } | |
86 | fprintf (stderr, | |
87 | "Server: connect from host %s, port %hd.\n", | |
88 | inet_ntoa (clientname.sin_addr), | |
89 | ntohs (clientname.sin_port)); | |
90 | FD_SET (new, &active_fd_set); | |
91 | } | |
92 | else | |
93 | { | |
94 | /* Data arriving on an already-connected socket. */ | |
95 | if (read_from_client (i) < 0) | |
96 | { | |
97 | close (i); | |
98 | FD_CLR (i, &active_fd_set); | |
99 | } | |
100 | } | |
101 | } | |
102 | } | |
103 | } |