Skip to content

Instantly share code, notes, and snippets.

@RyanScottLewis
Created March 28, 2013 08:14
Show Gist options
  • Save RyanScottLewis/5261549 to your computer and use it in GitHub Desktop.
Save RyanScottLewis/5261549 to your computer and use it in GitHub Desktop.
/*
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