According to the comments this is supposed to be a very basic echo server. It was written for school many years ago and I didn’t turn out to be a C coder after all, though I remember this being fun, so for anyone stumbling upon this: DISCLAIMER – apparently it was six in the morning and looks like I was a bit drunk too, so, seriously, don’t try it if you don’t know what it does. You shouldn’t run unknown code on your system, specially C code found on some random site, if anything happens, I don’t care. Just in case this does screw something up, drop me an email so I can laugh at you. Copy&pasted verbatim for archival purposes. Other than that it’s perfectly safe and no one lies on the internet.

/* this is a server that gets strings from a client
* and turns it into uppercase. does not do many checks
* and it could definitly be improved, but it works and
* that’s my only excuse. good enough for now. */
/* there are no #includes for the standard libs here
* because gcc knows about them. if you’ll use some
* other compiler you might want to add them if you
* get errors saying that printf() is not declared
* for example */
#include <sys/types.h> /* this is where the socket types are described */
#include <sys/socket.h> /* where the protocol families are described */
#include <stdlib.h> /* EXIT_FAILURE and EXIT_SUCCES macros are defined here */
#include <netinet/in.h> /* basic definitions for internet addreses (i.e. INADDR_ANY) */
#define MAXLINE 1024 /* max. number of bytes to be read from a line */
/* as a convention if a function returns -1 it means
* error. just so you know. */
upper_echo(int sockfd) /* this function will turn the string received from the client
* into uppercase and send it back on the socket
* i know this can be done better, but it seems to
* work even if it compiles with warnings */
char inc_str[MAXLINE]; /* the array where the incoming string will be stored */
char out_str[MAXLINE]; /* where the outgoing string will be stored */
int n; /* numer of char in array. used in the for loop */
int str_len; /* length of the string being read */
int connected=1; /* set to 0 if connection breaks down */
if((str_len=read(sockfd, inc_str, MAXLINE))<0)
/* read() attempts to read up to `MAXLINE’ bytes from file descriptor
* `sockfd’ into the buffer starting at `inc_str’. On success, the
* number of bytes read is returned (zero indicates end of file) */
perror(“Socket read error”);
/* perror() produces a message on the standard error output,
* describing the last error encountered. First the string is
* printed followed by a colon (:) and a blank. Then the message
* and a new-line. */
for (n=0;n<str_len;n++)
// printf(“inc_str: %s\n”,inc_str);
// printf(“out_str: %s\n”,out_str);
out_str[str_len]=NULL; /* adds NULL to the end of the string.
* otherwise, if the previous out_str
* was longer than this one, the extra
* chars will also be printed */
if(write(sockfd, out_str, MAXLINE)<0)
/* just like read(), but the other way around :) */
perror(“Socket write error”);
main(int argc, char *argv[])
/* In ISO C you can define `main’ either to take no arguments, or to
* take two arguments that represent the command line arguments to the
* program as shown above */
int port = atoi(argv[1]); /* the port to bind the socket to. it’s defined
   * here just for clearness sake */
int sockfd, newsockfd=1; /* socket file descriptor will be stored here */
int connected=1; /* set to 0 if connection breaks down */
// int s_name; /* socket name as returned by getsockname() will be stored here */
// socklen_t *len_ptr;
int new_pid; /* where the pid of the child process will be stored */
struct sockaddr_in s_addr, c_addr; /* defines s_addr (server_address) and c_addr (guess)
*  as a structure of type sockaddr_in */
/* – Data Type: struct sockaddr_in
*   This is the data type used to represent socket addresses in the
*   Internet namespace.  It has the following members:
*   `sa_family_t sin_family’
*      This identifies the address family or format of the socket
*      address.  You should store the value `AF_INET’ in this member.
*   `struct in_addr sin_addr’
*      This is the Internet address of the host machine.
*            IPv4 Internet host addresses are represented in some contexts as
*        integers (type `uint32_t’).  In other contexts, the integer is packaged
*        inside a structure of type `struct in_addr’ which has just one field,
*        named `s_addr’, which records the host address number as an `uint32_t’
*   `unsigned short int sin_port’
*      This is the port number */
size_t c_size; /* c_addr size will be stored here */
/* – Data Type: size_t
*   This is an unsigned integer type used to represent the sizes of objects
*   *Usage Note:* `size_t’ is the preferred way to declare any
*   arguments or variables that hold the size of an object */
if (port<=IPPORT_RESERVED) /* ports up to IPPORT_RESERVED are only for
* standard servers and only usable by root (1024 on linux) */
printf(“You specified port %d. Only ports higher than %d are allowed.\n”,port,IPPORT_RESERVED);
printf(“Server will be started on port %d\n”, port);
if ((sockfd=socket(PF_INET, SOCK_STREAM, 0))<0) /* creating the socket */
/* Socket() creates an endpoint for communication and returns a descriptor
* `AF_INET’ designates the address format that goes with the Internet namespace
*   meaning an IPv4 format internet address (
*  SOCK_STREAM provides sequenced, reliable, two-way, connection-based byte
*   streams.  An out-of-band data  transmission mechanism may be supported.
*      In one word, tcp. As opposed to SOCK_DGRAM which means udp.
* `0 or IPPROTO_TCP’ is the protocol used (tcp, the only one available with SOCK_STREAM) */
perror(“Socket creation error”);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons (port); /* host to network short. see below */
s_addr.sin_addr.s_addr = htonl (INADDR_ANY); /* Rather than finding and using the machine’s
  * Internet address, this example specifies
  * `INADDR_ANY’ as the host address; the system
  * replaces that with the machine’s actual address */
/* htonl() converts the unsigned integer `INADDR_ANY’ from host byte order to network byte order
*    On the i80x86 the host byte order is Least Significant Byte first, whereas the network
*    byte order, as used on the Internet, is Most Significant Byte first */
if (bind(sockfd, (struct sockaddr *) &s_addr, sizeof(s_addr))<0) /* bind the socket to an address */
/* bind gives the socket `sockfd’ the local address `s_addr’.
*     `s_addr’ is `sizeof(s_addr)’ bytes long. */
perror(“Socket binding error”);
if (listen(sockfd, 5)<0)
/* listen() specifies a willingness to accept incoming connections on `sockfd’
* and a queue limit (5) for incoming connections.
* The backlog parameter (5) defines the maximum length the queue of pending
* connections may grow to. */
printf(“Server started and listening for connections.\n”);
printf(“incoming connection… “);
if ((newsockfd=accept(sockfd, (struct sockaddr *) &c_addr, &c_size))<0)
/* accept() extracts the first connection request on the queue of
* pending connections, creates a new connected socket with mostly
* the same properties as `sockfd’, and allocates a new file descriptor
* for the socket, which is returned. The newly created socket is
* no longer in the listening state. The original socket `sockfd’ is
* unaffected by this call. In `c_addr’ and `c_size’ the address of the
* client and the the size of that address is stored.
* The call returns -1 on error. If it succeeds, it returns a
* non-negative integer that is a descriptor for the accepted socket. */
perror(“Accepting error”);
printf(“connection accepted\n”);
new_pid=fork(); /* fork a child that will deal with the new connection */
/* fork() returns the pid of the child to the parent
* and pid=0 to the child */
if(new_pid==0) /* if we are in the child process */
close(sockfd); /* close our copy of the original (listening) socket
* that socket is used by the parent, the child does not
* need it */
upper_echo(newsockfd); /* i am a child and i do my father’s work.
* is man a fork() of god ? :) */
else /* look, we are inside god :) */
close(newsockfd); /* close the connected socket. this is the daemon,
   * it only listens for connections the child takes
   * care of that socket and does all the work */
// (socklen_t *) &len_ptr=sizeof(s_addr);
// printf(“Socket name is: %d\n”, getsockname(sockfd, (struct sockaddr *) &s_addr, &len_ptr));
// close(sockfd);