Advertisement
coolizer

server

Mar 31st, 2014
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.56 KB | None | 0 0
  1. /*
  2. *  simpleServer.c
  3. *  1917 lab 4
  4. *
  5. *  Richard Buckland 28/01/11, 30/3/14.
  6. *  Licensed under Creative Commons SA-BY-NC 3.0, share freely.
  7. *
  8. */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include <netinet/in.h>
  15. #include <unistd.h>
  16.  
  17. int waitForConnection (int serverSocket);
  18. int makeServerSocket (int portno);
  19. void serveHTML (int socket);
  20.  
  21. #define SIMPLE_SERVER_VERSION 2.0
  22. #define REQUEST_BUFFER_SIZE 1000
  23. #define DEFAULT_PORT 7191
  24. #define NUMBER_OF_PAGES_TO_SERVE 10
  25. // after serving this many pages the server will halt
  26.  
  27. int main (int argc, char* argv[]) {
  28.  
  29.     printf ("************************************\n");
  30.     printf ("Starting simple server %f\n", SIMPLE_SERVER_VERSION);
  31.     printf ("Serving poetry since 2011\n");
  32.     printf ("Access this server at http://localhost:%d/\n", DEFAULT_PORT);
  33.     printf ("************************************\n");
  34.  
  35.     int serverSocket = makeServerSocket(DEFAULT_PORT);
  36.     char request[REQUEST_BUFFER_SIZE];
  37.     int numberServed = 0;
  38.     while (numberServed < NUMBER_OF_PAGES_TO_SERVE) {
  39.         printf ("*** So far served %d pages ***\n", numberServed);
  40.  
  41.         // STEP 1. wait for a request to be sent from a web browser,
  42.         // then open a new connection for this conversation
  43.         int connectionSocket = waitForConnection(serverSocket);
  44.  
  45.         // STEP 2. read the first line of the request
  46.         int bytesRead = recv (connectionSocket, request, sizeof(request) - 1, 0);
  47.         assert (bytesRead >= 0);
  48.         // check that we were able to read some data from the connection
  49.  
  50.         // echo entire request to the console for debugging
  51.         printf (" *** Received http request ***\n %s\n", request);
  52.  
  53.         // STEP 3. send the browser a simple html page using http
  54.         printf (" *** Sending http response ***\n");
  55.         serveHTML (connectionSocket);
  56.  
  57.         // STEP 4. close the connection after sending the page- keep aust beautiful
  58.         close (connectionSocket);
  59.         ++numberServed;
  60.     }
  61.  
  62.     // close the server connection after we are done- keep aust beautiful
  63.     printf ("** shutting down the server **\n");
  64.     close (serverSocket);
  65.  
  66.     return EXIT_SUCCESS;
  67. }
  68.  
  69. void serveHTML(int socket) {
  70.     const char* message =
  71.         "HTTP/1.1 200 OK\r\n"
  72.         "Content-Type: text/html\r\n"
  73.         "\r\n"
  74.         "<!DOCTYPE html>"
  75. "<html>"
  76. "<body>"
  77. "<h1><b><center>Alone in The Sky </h1></b></center>"
  78. "<center>"
  79. "<p>"
  80. "Among the flowers with wine beneath the sky<br>"
  81. "Alone I drink — no friend or kin, just me.<br>"
  82. "I raise my cup to toast the moon on high.<br>"
  83. "That's two of us; my shadow makes it three.<br>"
  84. "</p>"
  85. "<p>"
  86.  "   Alas, the poor moon knows not wine's delight. <br>"
  87.   "  My shadow follows like a living thing.<br>"
  88.    " At last with moon and shadow I unite<br>"
  89.     "In joyful bond, to seize the last of spring.<br>"
  90. "</p>"
  91. "<p>"
  92. "    I sing: it sets the moon to rock in time.<br>"
  93. "    I dance: my shadow cannot hold its place.<br>"
  94. "    Sober, we share companionship sublime;<br>"
  95. "    Drunk at last, we drift apart in space —<br>"
  96. "</p>"
  97. "<p>"
  98.  
  99. "    Lost to worldly things, until some day<br>"
  100. "    We'll meet again, beyond the Milky Way.<br>"
  101. "</p>"
  102. "</center>"
  103. "</body>"
  104. "</html>";
  105.  
  106.     // echo the http response to the console for debugging purposes
  107.     printf ("VVVV about to send this via http VVVV\n");
  108.     printf ("%s\n", message);
  109.     printf ("^^^^ end of message ^^^^\n");
  110.  
  111.     // send the http response to the web browser which requested it
  112.     send (socket, message, strlen(message), 0);
  113. }
  114.  
  115. // start the server listening on the specified port number
  116. int makeServerSocket (int portNumber) {
  117.  
  118.     // create socket
  119.     int serverSocket = socket (AF_INET, SOCK_STREAM, 0);
  120.     assert (serverSocket >= 0);
  121.     // check there was no error in opening the socket
  122.  
  123.     // bind the socket to the listening port  (7191 in this case)
  124.     struct sockaddr_in serverAddress;
  125.     serverAddress.sin_family      = AF_INET;
  126.     serverAddress.sin_addr.s_addr = INADDR_ANY;
  127.     serverAddress.sin_port        = htons (portNumber);
  128.  
  129.     // tell the server to restart immediately after a previous shutdown
  130.     // even if it looks like the socket is still in use
  131.     // otherwise we might have to wait a little while before rerunning the
  132.     // server once it has stopped
  133.     const int optionValue = 1;
  134.     setsockopt (serverSocket, SOL_SOCKET, SO_REUSEADDR, &optionValue, sizeof (int));
  135.  
  136.     int bindSuccess = bind (serverSocket, (struct sockaddr*)&serverAddress, sizeof (serverAddress));
  137.  
  138.     assert (bindSuccess >= 0);
  139.     // if this assert fails wait a short while to let the operating
  140.     // system clear the port before trying again
  141.  
  142.     return serverSocket;
  143. }
  144.  
  145. // wait for a browser to request a connection,
  146. // returns the socket on which the conversation will take place
  147. int waitForConnection (int serverSocket) {
  148.  
  149.     // listen for a connection
  150.     const int serverMaxBacklog = 10;
  151.     listen (serverSocket, serverMaxBacklog);
  152.  
  153.     // accept the connection
  154.     struct sockaddr_in clientAddress;
  155.     socklen_t clientLen = sizeof (clientAddress);
  156.     int connectionSocket = accept (serverSocket, (struct sockaddr*)&clientAddress, &clientLen);
  157.     assert (connectionSocket >= 0);
  158.     // check for connection error
  159.  
  160.     return connectionSocket;
  161. }
  162.  
  163. /*
  164. this code calls these external networking functions
  165. try to work out what they do from seeing how they are used,
  166. then google them for full details.
  167.  
  168. recv
  169. close
  170. send
  171. socket
  172. setsockopt
  173. bind
  174. listen
  175. accept
  176. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement