'How to receive and parse requests as an HTTP server?
For a class I have to implement an HTTP web server in C++. I currently have the server to the point that it can listen and accept connections, but I can't figure out how to accept data and parse it. When I send a request I get an error saying "Transport endpoint is nt connected." Here's what my code looks like so far:
int main(int argc, char *argv[]) {
// parse CLI args
if (argc != 3) { /** change to 3 once DOCROOT is added */
cout << "invalid arguments" << endl;
exit(1);
}
const char *DOCROOT = argv[1];
const char *PORT = argv[2];
// declare vars....from beej's so some not in use yet
int sockfd, new_fd;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr;
socklen_t sin_size;
struct sigaction sa;
int yes = 1;
char s[INET6_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
// try getaddrinfo
if ((rv = getaddrinfo(nullptr, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through getaddrinfo response and bind when possible
for (p=servinfo; p!=nullptr; p=p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (::bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(servinfo);
if (p == nullptr) {
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
/** choose backlog number and declare constant */
if (listen(sockfd, 5) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, nullptr) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections on port %s...\n", PORT);
while(true) { /** this will be the main accept loop */
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);
// receive
char recvbuf[1024];
int recvbuflen = 1024;
int request = recv(sockfd, recvbuf, recvbuflen, 0);
if (request == -1) perror("error receiving data");
if(send(new_fd, "Data received", 15, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
return 0;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
