Created
March 28, 2013 08:14
-
-
Save RyanScottLewis/5261549 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
NAME: TCPServer | |
SYNOPSIS: TCPServer [port] | |
DESCRIPTION: The program creates a TCP socket in the inet | |
listen for connections from TCPClients, | |
accept clients into private sockets, and | |
fork an echo process to ``serve'' the client. | |
If [port] is not specified, the program uses any available port. | |
*/ | |
#include "def" | |
void exit(int); | |
#define MAXHOSTNAME 80 | |
void reusePort(int sock); | |
main( argc, argv ) | |
int argc; | |
char *argv[]; | |
{ | |
int sd, psd; | |
struct sockaddr_in server; | |
struct hostent *hp, *gethostbyname(); | |
struct servent *sp; | |
struct sockaddr_in from; | |
int fromlen; | |
int length; | |
char ThisHost[80]; | |
int pn; | |
int childpid; | |
sp = getservbyname("echo", "tcp"); | |
/* get TCPServer1 Host information, NAME and INET ADDRESS */ | |
gethostname(ThisHost, MAXHOSTNAME); | |
/* OR strcpy(ThisHost,"localhost"); */ | |
printf("----TCP/Server running at host NAME: %s\n", ThisHost); | |
if ( (hp = gethostbyname(ThisHost)) == NULL ) { | |
fprintf(stderr, "Can't find host %s\n", argv[1]); | |
exit(-1); | |
} | |
bcopy ( hp->h_addr, &(server.sin_addr), hp->h_length); | |
printf(" (TCP/Server INET ADDRESS is: %s )\n", inet_ntoa(server.sin_addr)); | |
/** Construct name of socket */ | |
server.sin_family = AF_INET; | |
/* OR server.sin_family = hp->h_addrtype; */ | |
server.sin_addr.s_addr = htonl(INADDR_ANY); | |
if (argc == 1) | |
server.sin_port = htons(0); | |
else { | |
pn = htons(atoi(argv[1])); | |
server.sin_port = pn; | |
} | |
/*OR server.sin_port = sp->s_port; */ | |
/** Create socket on which to send and receive */ | |
sd = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP); | |
/* OR sd = socket (hp->h_addrtype,SOCK_STREAM,0); */ | |
if (sd<0) { | |
perror("opening stream socket"); | |
exit(-1); | |
} | |
/** this allow the server to re-start quickly instead of fully wait | |
for TIME_WAIT which can be as large as 2 minutes */ | |
reusePort(sd); | |
if ( bind( sd, (SA *) &server, sizeof(server) ) < 0 ) { | |
close(sd); | |
perror("binding name to stream socket"); | |
exit(-1); | |
} | |
/** get port information and prints it out */ | |
length = sizeof(server); | |
if ( getsockname (sd, (SA *)&server,&length) ) { | |
perror("getting socket name"); | |
exit(0); | |
} | |
printf("Server Port is: %d\n", ntohs(server.sin_port)); | |
/** accept TCP connections from clients and fork a process to serve each */ | |
listen(sd,4); | |
fromlen = sizeof(from); | |
for(;;){ | |
psd = accept(sd, (SA *)&from, &fromlen); | |
childpid = fork(); | |
if ( childpid == 0) { | |
close (sd); | |
EchoServe(psd, from); | |
} | |
else{ | |
printf("My new child pid is %d\n", childpid); | |
close(psd); | |
} | |
} | |
} | |
EchoServe(psd, from) | |
int psd; | |
struct sockaddr_in from; | |
{ | |
char buf[512]; | |
int rc; | |
struct hostent *hp, *gethostbyname(); | |
printf("Serving %s:%d\n", inet_ntoa(from.sin_addr), | |
ntohs(from.sin_port)); | |
if ((hp = gethostbyaddr((char *)&from.sin_addr.s_addr, | |
sizeof(from.sin_addr.s_addr),AF_INET)) == NULL) | |
fprintf(stderr, "Can't find host %s\n", inet_ntoa(from.sin_addr)); | |
else | |
printf("(Name is : %s)\n", hp->h_name); | |
/** get data from clients and send it back */ | |
for(;;){ | |
printf("\n...server is waiting...\n"); | |
if( (rc=recv(psd, buf, sizeof(buf), 0)) < 0){ | |
perror("receiving stream message"); | |
exit(-1); | |
} | |
if (rc > 0){ | |
buf[rc]=NULL; | |
printf("Received: %s\n", buf); | |
printf("From TCP/Client: %s:%d\n", inet_ntoa(from.sin_addr), | |
ntohs(from.sin_port)); | |
printf("(Name is : %s)\n", hp->h_name); | |
if (send(psd, buf, rc, 0) <0 ) | |
perror("sending stream message"); | |
} | |
else { | |
printf("TCP/Client: %s:%d\n", inet_ntoa(from.sin_addr), | |
ntohs(from.sin_port)); | |
printf("(Name is : %s)\n", hp->h_name); | |
printf("Disconnected..\n"); | |
close (psd); | |
exit(0); | |
} | |
} | |
} | |
void reusePort(int s) | |
{ | |
int one=1; | |
if ( setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *) &one,sizeof(one)) == -1 ) | |
{ | |
printf("error in setsockopt,SO_REUSEPORT \n"); | |
exit(-1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment