Last active
June 5, 2020 22:42
-
-
Save ShivamShrirao/5373659efb11082b0b43eba594c47017 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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