ComputerScienceExpert

(11)

$18/per page/

About ComputerScienceExpert

Levels Tought:
Elementary,Middle School,High School,College,University,PHD

Expertise:
Applied Sciences,Calculus See all
Applied Sciences,Calculus,Chemistry,Computer Science,Environmental science,Information Systems,Science Hide all
Teaching Since: Apr 2017
Last Sign in: 103 Weeks Ago, 2 Days Ago
Questions Answered: 4870
Tutorials Posted: 4863

Education

  • MBA IT, Mater in Science and Technology
    Devry
    Jul-1996 - Jul-2000

Experience

  • Professor
    Devry University
    Mar-2010 - Oct-2016

Category > Programming Posted 02 May 2017 My Price 11.00

Week 7 Lab—Networking and a Tiny Web Server

I need some help with part A of this iLab Ive been trying to compile to code but i cant get it to work or get a screenshot. 

 

 

Week 7 Lab—Networking and a Tiny Web Server
TCO 1—Given a computing environment with multiple operating systems,
demonstrate the ability to use the command line interface in Windows and Linux, and
compile and run a program using the command line.
TCO 10—Given the importance of networking in game design, explain how computers
are connected to a network, and summarize basic networking fundamentals,
terminologies, protocols, and devices.
Scenario
In this week's lab, we will create two C programs to use with networking commands.
The first program will read a domain name or dotted-decimal address from the
command line and display the corresponding host entry. The second program will be
a tiny web server used on localhost. Rubric
Point distribution for this activity.
Lab Activity
Document Points
possible Part A: hostinfo.c 20 Part B: tiny web server 20
Total Points Points received 40 Part A:
In this lab, we will explore DNS mapping by creating a file named hostinfo.c. This
program will read a domain name or dotted-decimal address from the command line and
display the corresponding host entry. Local host will always map to 127.0.0.2.
Enter the following C code into notepad. Save the file in the cygwin\home\username
folder on your computer (ie: C:\cygwin64\home\gina) as hostinfo.c.
Open Cygwin, and compile the program: gcc hostinfo.c –o hostinfo. #include <stdlib.h> #include <stdio.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv)
{
char **pp;
struct in_addr addr;
struct hostent *hostp;
if(argc!=2)
{
fprintf(stderr, "usage: %s <domain name or dotteddecimal>\n", argv[0]);
exit(0);
}
if(inet_aton(argv[1], &addr)!=0)
hostp = gethostbyaddr((const char*)&addr, sizeof(addr),
AF_INET);
else
hostp = gethostbyname(argv[1]);
printf("official hostname: %s\n", hostp->h_name);
for(pp=hostp->h_aliases; *pp!=NULL; pp++)
printf("alias: %s\n",*pp);
for(pp=hostp->h_addr_list; *pp!=NULL; pp++)
{
addr.s_addr=((struct in_addr*)*pp)->s_addr;
printf("address: %s\n", inet_ntoa(addr)); //ntoa is
network to application,
//returns pointer to dotted-decimal string
}
exit(0);
} Run the program with the following domain names, and note the results. Also, choose
some of your own. ./hostinfo localhost Paste screenshot results for:
Google.com
com
A web address of your choosing:
Part B:
Read pages 919-927 in the book. We will be developing the tiny web server listed in the
book. This web server supports the GET method. It will look for an HTML file in the
current directory and will display the web page in a web browser. Please study and
review the code to understand what it is doing. Feel free to extend the code as well.
Copy the C code below into notepad. Save the file in the cygwin\home\username folder
on your computer (i.e., C:\cygwin64\home\gina) as tiny.c.
Compile the program: gcc tiny.c –o tiny.
In another notepad file, create a simple HTML file called home.html with your name and
any other information in it. Save this in your cygwin\home\username directory. It should
be in the same directory as tiny.c. The web page can be as simple as:
<html>
<body>
<h1> I love GSP215</h1>
<p>My name is Kara Thrace</p>
</body>
</html>
To run the program, at a cygwin prompt, type ./tiny 10000.
This will start the web server listening at port 10000.
Open your web browser, and type the following in the address bar:
http://localhost:10000/home.html.
This will open your website using your own tiny web server. To stop your tiny web server, press control + c in cygwin. Include a screenshot below of your web page working in a browser. C Code:
//Tiny web server code
#include <stdlib.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define MAXLINE 8192 //max text line length #define MAXBUF
8192 /* max I/O buffer size */
typedef struct sockaddr SA; //socaddrdef
#define LISTENQ 1024
#define RIO_BUFSIZE 8192
typedef struct {
int rio_fd;
buf */
int rio_cnt;
*/
char *rio_bufptr;
buf */
char rio_buf[RIO_BUFSIZE];
} rio_t; /* descriptor for this internal
/* unread bytes in internal buf
/* next unread byte in internal
/* internal buffer */ //Wrapper for the unix read() function that
//transfers min(n, rio_cnt) bytes from an internal buffer
//to a user buffer
static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n)
{
int cnt;
while (rp->rio_cnt <= 0) { /* refill if buf is empty */
rp->rio_cnt = read(rp->rio_fd, rp->rio_buf,
sizeof(rp->rio_buf));
if (rp->rio_cnt < 0) {
if (errno != EINTR) /* interrupted by sig handler
return */
return -1;
}
else if (rp->rio_cnt == 0) /* EOF */
return 0;
else
rp->rio_bufptr = rp->rio_buf; /* reset buffer ptr */
}
/* Copy min(n, rp->rio_cnt) bytes from internal buf to
user buf */
cnt = n;
if (rp->rio_cnt < n)
cnt = rp->rio_cnt;
memcpy(usrbuf, rp->rio_bufptr, cnt);
rp->rio_bufptr += cnt;
rp->rio_cnt -= cnt;
return cnt; }
//wrapper for the unix read() function that transfers min(n,
rio_cnt) bytes
//from an internal buffer to a user buffer
ssize_t rio_writen(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nwritten;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nwritten = write(fd, bufp, nleft)) <= 0) {
if (errno == EINTR) /* interrupted by sig handler
return */
nwritten = 0;
/* and call write() again */
else
return -1;
/* errorno set by write() */
}
nleft -= nwritten;
bufp += nwritten;
}
return n;
}
//robustly read a text line (buffered)
ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
{
int n, rc;
char c, *bufp = usrbuf;
for (n = 1; n < maxlen; n++) {
if ((rc = rio_read(rp, &c, 1)) == 1) {
*bufp++ = c;
if (c == '\n')
break;
} else if (rc == 0) {
if (n == 1)
return 0; /* EOF, no data read */
else
break;
/* EOF, some data was read */
} else
return -1;
/* error */
}
*bufp = 0;
return n;
} //Associate a descriptor with a read buffer and reset buffer
void rio_readinitb(rio_t *rp, int fd)
{
rp->rio_fd = fd;
rp->rio_cnt = 0;
rp->rio_bufptr = rp->rio_buf;
}
//open connection to server at <hostname, port>
//and return a socket descriptor ready for reading and writing
int open_clientfd(char *hostname, int port)
{
int clientfd;
struct hostent *hp;
struct sockaddr_in serveraddr;
if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1; /* check errno for cause of error */
/* Fill in the server's IP address and port */
if ((hp = gethostbyname(hostname)) == NULL)
return -2; /* check h_errno for cause of error */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)hp->h_addr_list[0],
(char *)&serveraddr.sin_addr.s_addr, hp->h_length);
serveraddr.sin_port = htons(port);
/* Establish a connection with the server */
if (connect(clientfd, (SA *) &serveraddr,
sizeof(serveraddr)) < 0)
return -1;
return clientfd;
}
//Open and return a listening socket on port
int open_listenfd(int port)
{
int listenfd, optval=1;
struct sockaddr_in serveraddr;
/* Create a socket descriptor */
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
/* Eliminates "Address already in use" error from bind. */
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)) < 0)
return -1;
/* Listenfd will be an endpoint for all requests to port
on any IP address for this host */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)port);
if (bind(listenfd, (SA *)&serveraddr, sizeof(serveraddr)) < 0) return -1;
/* Make it a listening socket ready to accept connection
requests */
if (listen(listenfd, LISTENQ) < 0)
return -1;
return listenfd;
} void doit(int fd);
void read_requesthdrs(rio_t *rp);
int parse_uri(char *uri, char *filename, char *cgiargs);
void serve_static(int fd, char *filename, int filesize);
void get_filetype(char *filename, char *filetype);
void serve_dynamic(int fd, char *filename, char *cgiargs);
void clienterror(int fd, char *cause, char *errnum,
char *shortmsg, char *longmsg);
int main(int argc, char **argv)
{
int listenfd, connfd, port, clientlen;
struct sockaddr_in clientaddr;
/* Check command line args */
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
port = atoi(argv[1]);
listenfd = open_listenfd(port);
while (1) {
clientlen = sizeof(clientaddr);
connfd = accept(listenfd, (SA *)&clientaddr, &clientlen);
doit(connfd);
close(connfd); }
}
/* $end tinymain */
/*
* doit - handle one HTTP request/response transaction
*/
/* $begin doit */
void doit(int fd)
{
int is_static;
struct stat sbuf;
char buf[MAXLINE], method[MAXLINE], uri[MAXLINE],
version[MAXLINE];
char filename[MAXLINE], cgiargs[MAXLINE];
rio_t rio;
/* Read request line and headers */
rio_readinitb(&rio, fd);
rio_readlineb(&rio, buf, MAXLINE);
sscanf(buf, "%s %s %s", method, uri, version);
if (strcasecmp(method, "GET")) {
clienterror(fd, method, "501", "Not Implemented",
"Tiny does not implement this method");
return;
}
read_requesthdrs(&rio);
/* Parse URI from GET request */
is_static = parse_uri(uri, filename, cgiargs);
if (stat(filename, &sbuf) < 0) {
clienterror(fd, filename, "404", "Not found",
"Tiny couldn't find this file");
return;
}
if (is_static) { /* Serve static content */
if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR &
sbuf.st_mode)) {
clienterror(fd, filename, "403", "Forbidden",
"Tiny couldn't read the file");
return;
}
serve_static(fd, filename, sbuf.st_size);
}
else { /* Serve dynamic content */
if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR &
sbuf.st_mode)) {
clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program");
return; }
serve_dynamic(fd, filename, cgiargs); }
}
/* $end doit */ /*
* read_requesthdrs - read and parse HTTP request headers
*/
/* $begin read_requesthdrs */
void read_requesthdrs(rio_t *rp)
{
char buf[MAXLINE];
rio_readlineb(rp, buf, MAXLINE);
printf("%s", buf);
while(strcmp(buf, "\r\n")) {
rio_readlineb(rp, buf, MAXLINE);
printf("%s", buf);
}
return;
}
/* $end read_requesthdrs */
/*
* parse_uri - parse URI into filename and CGI args
*
return 0 if dynamic content, 1 if static
*/
/* $begin parse_uri */
int parse_uri(char *uri, char *filename, char *cgiargs)
{
char *ptr;
if (!strstr(uri, "cgi-bin")) { /* Static content */
strcpy(cgiargs, "");
strcpy(filename, ".");
strcat(filename, uri);
if (uri[strlen(uri)-1] == '/')
strcat(filename, "home.html");
return 1;
}
else { /* Dynamic content */
ptr = index(uri, '?');
if (ptr) {
strcpy(cgiargs, ptr+1);
*ptr = '\0';
} else
strcpy(cgiargs, "");
strcpy(filename, ".");
strcat(filename, uri);
return 0;
}
}
/* $end parse_uri */
/*
* serve_static - copy a file back to the client
*/
/* $begin serve_static */
void serve_static(int fd, char *filename, int filesize)
{
int srcfd;
char *srcp, filetype[MAXLINE], buf[MAXBUF];
/* Send response headers to client */
get_filetype(filename, filetype);
sprintf(buf, "HTTP/1.0 200 OK\r\n");
sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);
sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
rio_writen(fd, buf, strlen(buf));
/* Send response body to client */
srcfd = open(filename, O_RDONLY, 0);
srcp = mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd,
0); close(srcfd);
rio_writen(fd, srcp, filesize);
munmap(srcp, filesize); }
/*
* get_filetype - derive file type from file name
*/
void get_filetype(char *filename, char *filetype)
{
if (strstr(filename, ".html"))
strcpy(filetype, "text/html");
else if (strstr(filename, ".gif"))
strcpy(filetype, "image/gif");
else if (strstr(filename, ".jpg"))
strcpy(filetype, "image/jpeg");
else
strcpy(filetype, "text/plain");
} /* $end serve_static */
/*
* serve_dynamic - run a CGI program on behalf of the client
*/
/* $begin serve_dynamic */
void serve_dynamic(int fd, char *filename, char *cgiargs)
{
char buf[MAXLINE], *emptylist = { NULL };
/* Return first part of HTTP response */
sprintf(buf, "HTTP/1.0 200 OK\r\n");
rio_writen(fd, buf, strlen(buf));
sprintf(buf, "Server: Tiny Web Server\r\n");
rio_writen(fd, buf, strlen(buf));
if (fork() == 0) { /* child */
/* Real server would set all CGI vars here */
setenv("QUERY_STRING", cgiargs, 1);
dup2(fd, STDOUT_FILENO);
/* Redirect stdout to
client */
execve(filename, emptylist, environ); /* Run CGI program
*/
}
wait(NULL); /* Parent waits for and reaps child */
}
/* $end serve_dynamic */
/*
* clienterror - returns an error message to the client
*/
/* $begin clienterror */
void clienterror(int fd, char *cause, char *errnum,
char *shortmsg, char *longmsg)
{
char buf[MAXLINE], body[MAXBUF];
/* Build the HTTP response body */
sprintf(body, "<html><title>Tiny Error</title>");
sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body);
sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg);
sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);
sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n",
body);
/* Print the HTTP response */
sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg);
rio_writen(fd, buf, strlen(buf));
sprintf(buf, "Content-type: text/html\r\n"); rio_writen(fd, buf, strlen(buf));
sprintf(buf, "Content-length: %d\r\n\r\n",
(int)strlen(body));
rio_writen(fd, buf, strlen(buf));
rio_writen(fd, body, strlen(body));
}
/* $end clienterror */

Answers

(11)
Status NEW Posted 02 May 2017 09:05 AM My Price 11.00

-----------

Not Rated(0)