Noob here. I have been following Beej’s Guide to Network Programming and tried constructing an HTTP server following the style of code used in the book. I am running FreeBSD 14.0.
My issue is that all my server programs require two instances running at once in order to successfully render the connection — IOW, starting the program twice via ./httpserver & ./httpserver
or an equivalent method. The connection will be refused if only one instance is running.
The code below is for my stupid-simple concurrent HTTP server. I also tried one using the select() function for a different approach, but it had the same exact quirk (needing two running instances to work).
// include statements omitted
int main(void) {
int sockfd;
int rv;
int yes = 1;
struct addrinfo hints, *res, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, "8000", &hints, &res)) != 0) {
fprintf(stderr, "httpserver: %sn", gai_strerror(rv));
exit(1);
}
for (p = res; p != NULL; p = p->ai_next) {
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockfd < 0) {
continue;
}
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
if (bind(sockfd, p->ai_addr, p->ai_addrlen) < 0) {
close(sockfd);
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "httpserver: could not bind to any addressn");
freeaddrinfo(res);
exit(1);
}
freeaddrinfo(res);
if (listen(sockfd, 10) == -1) {
perror("listen");
exit(1);
}
// main loop.
while (1) {
int newfd;
struct sockaddr_storage theiraddr;
socklen_t addrlen;
addrlen = sizeof(theiraddr);
newfd = accept(sockfd, (struct sockaddr*)&theiraddr, &addrlen);
if (newfd == -1) {
perror("accept");
continue;
}
if (!fork()) { // Child process
close(sockfd); // Child doesn't need the listener
char buf[4096];
int nbytes = recv(newfd, buf, sizeof(buf), 0);
if (nbytes > 0) {
buf[nbytes] = '';
printf("Received request: %sn", buf);
// Simple HTTP response
const char *response =
"HTTP/1.1 200 OKrn"
"Content-Type: text/htmlrn"
"Content-Length: 70rn"
"rn"
"<html><head><title>Test</title></head><body><h1>Hello, World!</h1></body></html>";
if (send(newfd, response, strlen(response), 0) == -1) {
perror("send");
}
} else if (nbytes == 0) {
printf("server: socket %d hung upn", newfd);
} else {
perror("recv");
}
close(newfd);
exit(0); // Exit child process after handling connection
}
// Parent process
close(newfd); // Parent doesn't need this socket
}
close(sockfd);
return 0;
}
Could anyone share why they think this is happening?
JoshHellauer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.