Last active
September 14, 2015 01:31
-
-
Save khanzf/4cfdf19af62462d93057 to your computer and use it in GitHub Desktop.
Multiserv
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 <string.h> | |
#include <netdb.h> | |
#include <netinet/in.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/time.h> | |
#include <sys/socket.h> | |
#include <sys/uio.h> | |
#include <arpa/inet.h> | |
struct clientinfo { | |
int fd; | |
struct sockaddr_in info; | |
}; | |
int rmfd(struct clientinfo *connects, int location, int numcon) { | |
int count; | |
struct clientinfo *temp; | |
for(count=location;count<=numcon;count++) | |
connects[count] = connects[count+1]; | |
temp = malloc(sizeof(struct clientinfo)*(numcon-1+(numcon-1==0))); | |
for(count=0;count<numcon-1;count++) { | |
temp[count] = connects[count]; | |
} | |
connects = malloc(sizeof(struct clientinfo)*(numcon-1+(numcon-1==0))); | |
for(count=0;count<numcon-1;count++) { | |
connects[count] = temp[count]; | |
} | |
return numcon-1; | |
} | |
int addfd(struct clientinfo *connects, int numcon) { | |
struct clientinfo *temp; | |
int count; | |
temp = malloc(sizeof(struct clientinfo) * (numcon+(numcon==0))); | |
for(count=0;count<numcon;count++) { | |
temp[count].fd = connects[count].fd; | |
temp[count].info = connects[count].info; | |
} | |
connects = malloc(sizeof(struct clientinfo)*(numcon+1)); | |
for(count=0;count<numcon;count++) { | |
connects[count].fd = temp[count].fd; | |
connects[count].info = temp[count].info; | |
} | |
return numcon+1; | |
} | |
int main(int argc, char **argv) { | |
int check; | |
int sin_size; | |
int numcon; | |
int maxfd; | |
int readtest; | |
int writecount; | |
char rwbuf[1024]; | |
struct timeval timer; | |
struct clientinfo *connects; | |
fd_set sockrd; | |
if (argc != 2) { | |
fprintf(stderr, "usage: %s port\n", argv[0]); | |
exit(-1); | |
} | |
sin_size = sizeof(struct sockaddr); | |
numcon = 0; | |
connects = malloc(sizeof(struct clientinfo)); | |
FD_ZERO(&sockrd); | |
connects[0].info.sin_family = AF_INET; | |
connects[0].info.sin_port = htons(atoi(argv[1])); | |
connects[0].info.sin_addr.s_addr = INADDR_ANY; | |
connects[0].fd = socket(AF_INET, SOCK_STREAM, 0); | |
check = bind(connects[0].fd, (struct sockaddr *)&connects[0].info, sizeof(struct sockaddr)); | |
if(check == -1) { | |
perror("bind"); | |
exit(check); | |
} | |
check = listen(connects[0].fd, 1024); | |
if (check == -1) { | |
perror("listen"); | |
exit(check); | |
} | |
maxfd = connects[0].fd; | |
for(;;) { | |
FD_ZERO(&sockrd); | |
FD_SET(connects[0].fd, &sockrd); | |
for(check=1;check<=numcon;check++) | |
FD_SET(connects[check].fd, &sockrd); | |
timer.tv_sec = 60; | |
timer.tv_usec = 0; | |
select(maxfd+1, &sockrd, NULL, NULL, &timer); | |
if (FD_ISSET(connects[0].fd, &sockrd)) { | |
sin_size = sizeof(struct sockaddr_in); | |
numcon = addfd(connects, numcon); | |
connects[numcon].fd = accept(connects[0].fd, (struct sockaddr *)&connects[numcon].info, &sin_size); | |
if (connects[numcon].fd > maxfd) | |
maxfd = connects[numcon].fd; | |
} | |
else { | |
for(readtest=1;readtest<=numcon;readtest++) { | |
if(FD_ISSET(connects[readtest].fd, &sockrd)) { | |
memset(rwbuf, 0, 1024); | |
check = read(connects[readtest].fd, rwbuf, 1024); | |
if (check == 0) { | |
close(connects[readtest].fd); | |
numcon = rmfd(connects, readtest, numcon); | |
} | |
else { | |
for(writecount=1;writecount<=numcon;writecount++) { | |
if (writecount != readtest) | |
write(connects[writecount].fd, rwbuf, 1024); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code handles multiple IPv4 sockets and relays data from one to the rest. It does not utilize fork(2).
I wrote this as the frame for a chat program I had planned on writing back in 2001, but never finished. However, I was quite happy with this snippet of code.
I doubt it has any practical application, especially in modern computing environments where distributed frameworks use multi-threading, but I hope it serves as an effective teaching tool.