Skip to content

Instantly share code, notes, and snippets.

@ShivamShrirao
Last active June 5, 2020 22:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShivamShrirao/5373659efb11082b0b43eba594c47017 to your computer and use it in GitHub Desktop.
Save ShivamShrirao/5373659efb11082b0b43eba594c47017 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void handle_request(int cfd){
char prompt[] = "Enter message: ";
char msg[200];
write(cfd, prompt, strlen(prompt));
read(cfd, msg, 1024);
// process the message.
}
int main(int argc, char const *argv[])
{
int PORT=0;
if(argc > 1){
PORT = atoi(argv[1]); // get port to listen on from first argument.
}
if(!PORT){
PORT=8888;
}
int sfd,opt=1,cfd;
if((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ // initialize tcp server socket file descriptor.
printf("[!] socket failed.\n");
exit(-1);
}
struct sockaddr_in s_addr; // struct to hold server socket configurations.
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) < 0){ // So that multiple clients can connect to server at same time.
printf("[!] setsockopt failed.\n");
exit(-1);
}
s_addr.sin_family=AF_INET;
s_addr.sin_port=htons(PORT);
s_addr.sin_addr.s_addr=INADDR_ANY; // any available address (listens on all interfaces i.e. 0.0.0.0)
if(bind(sfd,(struct sockaddr*)&s_addr, sizeof(s_addr)) < 0){ // bind to the port
printf("[!] bind failed.\n");
exit(-1);
}
if(listen(sfd,10) < 0){ // start listening for connections.
printf("[!] listen failed.\n");
exit(-1);
}
char sip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(s_addr.sin_addr), sip, INET_ADDRSTRLEN); // server ip address
printf("[i] Listening on %s:%d, sfd is %d\n", sip, PORT, sfd);
struct sockaddr_in c_addr; // struct to hold client.
socklen_t addr_len = sizeof(c_addr);
while(1){
if((cfd = accept(sfd,(struct sockaddr*)&c_addr,(socklen_t*)&addr_len)) < 0){ // accept connection from client
printf("[!] accept failed.\n");
}
else{
pid_t pid;
if((pid=fork()) == 0){ // fork, create new child process to handle the request.
close(sfd); // close server file descriptor in child.
char cip[INET_ADDRSTRLEN];
int cport = ntohs(c_addr.sin_port); // client port
inet_ntop(AF_INET, &(c_addr.sin_addr), cip, INET_ADDRSTRLEN); // client ip address
printf("[*] Accepted, cfd %d from %s:%d, pid: %d\n", cfd, cip, cport, getpid());
handle_request(cfd);
char closing[] = "Request complete, Closing...\n";
write(cfd, closing, strlen(closing)); // closing message.
close(cfd);
exit(0); // exit child after client is served.
}
else{
signal(SIGCHLD,SIG_IGN); // ignore exit status of child to kill zombie child.
close(cfd); // close connection in parent process.
}
}
}
close(sfd); // program won't actually reach this.
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment