1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
void server(SERVERCONN* const conn) {
int res = 0;
boolean y = True;
printf("Starting server mode...\n");
if ((res = getaddrinfo(NULL, conn->port,
&conn->hints, &conn->servinfo
)) != 0) {
fprintf(stderr, "server: getaddrinfo error: %s\n", gai_strerror(res));
die("");
}
/* Bind to the first socket connection we can */
for (conn->p = conn->servinfo; conn->p != NULL; conn->p = conn->p->ai_next) {
if ((conn->sockfd = socket(conn->p->ai_family, conn->p->ai_socktype,
conn->p->ai_protocol)) == -1) {
perror("server: socket error");
continue;
}
if (setsockopt(conn->sockfd, SOL_SOCKET,
SO_REUSEADDR, &y, sizeof(int)
) == -1) {
perror("server: setsockopt error");
die("");
}
if (bind(conn->sockfd, conn->p->ai_addr, conn->p->ai_addrlen) == -1) {
close(conn->sockfd);
perror("server: bind error");
die("");
}
break; /* die() or continue should have occurred before here
* if something went wrong
*/
}
if (conn->p == NULL) /* Uh-oh! */
die("server: failed to bind\n");
freeaddrinfo(conn->servinfo); /* Free the structure, we don't need it any more */
printf("server: bound\n");
if (listen(conn->sockfd, conn->queuelen) == -1) {
perror("server: listen error");
die("");
}
conn->sa.sa_handler = (void*)handleSignal;
sigemptyset(&conn->sa.sa_mask);
conn->sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &conn->sa, NULL) == -1) {
perror("server: sigaction error");
die("");
}
printf("server: awaiting client connections\n");
for (;;) {
conn->sin_size = sizeof(conn->client_addr);
printf("Accepting connection...");
conn->new_sockfd = accept(conn->sockfd,
(struct sockaddr*)&(conn->client_addr),
(socklen_t*)&(conn->sin_size)
);
if (conn->new_sockfd == -1) {
perror("server: unable to accept client connection");
continue;
}
printf(" done.\n");
/* inet_ntop */
inet_ntop(conn->client_addr.ss_family,
getInAddress((struct sockaddr*)&(conn->client_addr)),
conn->addr_str, sizeof(conn->addr_str)
);
printf("server: success; connected to %s\n", conn->addr_str);
pid_t pid = fork();
switch (pid) {
case -1: /* Fuey. */
perror("server: fork error");
die("");
case 0: /* Child process */
close(conn->sockfd); /* Don't need to listen on the socket */
if (send(conn->new_sockfd, "HELLO", 13, 0) == -1)
perror("server: send error");
if (send(conn->new_sockfd, "BYE", 13, 0) == -1)
perror("server: send error");
close(conn->new_sockfd); /* Close connection */
done();
default:
close(conn->new_sockfd); /* Don't need to write to the socket */
break;
}
}
}
|