Top Banner
Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao [email protected] Office hours: Thursdays 5-6PM Wean Hall 1315
23

Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao [email protected] Office hours: Thursdays.

Jan 03, 2016

Download

Documents

Jeffry Norman
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Recitation 12 (Nov. 29)

Outline Socket programming Lab 7: part 1

Reminder Lab 7:

Due next Thursday

Minglong [email protected]

Office hours:Thursdays 5-6PMWean Hall 1315

Page 2: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Extending echo server

Recap the echo client and server Extend the echo server to build an echo proxy

Page 3: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

An echo client-server transaction

EchoClient

process

EchoServer

process

1. Client sends an input line

2. Server sends the same text as it receives3. Client displays the text

it receives

Page 4: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

rio_readlineb

close

closeEOF

rio_readlineb

rio_writenrio_readlineb

rio_writen

listen

bind

Review of the sockets interfaceClient Server

socket socket

acceptconnect

Connectionrequest

Await connectionrequest fromnext client

open_listenfd

open_clientfd

Page 5: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Key data structure Defined in /usr/include/netinet/in.h /usr/include/bits/socket.h

Must cast (sockaddr_in *) to (sockaddr *) for connect, bind, and accept

/* generic socket address */struct sockaddr { unsigned short sa_family; /* protocol family */ char sa_data[14]; /* address data */};

/* internet specific socket address */struct sockaddr_in { unsigned short sin_family; /* address family: AF_INET) */ unsigned short sin_port; /* port number (big-endian) */ struct in_addr sin_addr; /* IP address (big-endian) */ unsigned char sin_zero[8]; /* padding */};

Page 6: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo client main routine#include "csapp.h"

/* usage: ./echoclient host port */int main(int argc, char **argv){ int clientfd, port; char *host, buf[MAXLINE]; rio_t rio; host = argv[1]; port = atoi(argv[2]); clientfd = Open_clientfd(host, port); Rio_readinitb(&rio, clientfd); while (Fgets(buf, MAXLINE, stdin) != NULL) { Rio_writen(clientfd, buf, strlen(buf)); Rio_readlineb(&rio, buf, MAXLINE); Fputs(buf, stdout); } Close(clientfd); exit(0); }

Page 7: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo client: open_clientfdint 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, (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; }

This function opens a connection from the client to the server at hostname:port

Page 8: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo server: main routineint main(int argc, char **argv) { int listenfd, connfd, port, clientlen; struct sockaddr_in clientaddr; struct hostent *hp; char *haddrp;

port = atoi(argv[1]); /* the server listens on a port passed on the command line */ listenfd = open_listenfd(port);

while (1) { clientlen = sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET); haddrp = inet_ntoa(clientaddr.sin_addr); printf("server connected to %s (%s)\n", hp->h_name, haddrp); echo(connfd); Close(connfd); }}

Page 9: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo server: open_listenfdint 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; ... (more)

Page 10: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo server: open_listenfd (cont)...

/* 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; }

Page 11: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Echo server: echovoid echo(int connfd) { size_t n; char buf[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { printf("server received %d bytes\n", n); Rio_writen(connfd, buf, n); } }

Page 12: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Proxy

A proxy is an intermediary between a client and a real server. To the client, the proxy acts like a server. To the server, the proxy acts like a client.

EchoClient

process

EchoServer

process

Echoproxy

process

Page 13: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Change ”echo” procedurevoid echo_forward(int connfd, char *server, int server_port) { int forwardfd; rio_t rio_conn, rio_forward; ssize_t n; char buf[MAXLINE];

/* connect to the server */ forwardfd = Open_clientfd(server, server_port); Rio_readinitb(&rio_forward, forwardfd);

Rio_readinitb(&rio_conn, connfd); while (1) { if ((n = Rio_readlineb(&rio_conn, buf, MAXLINE)) == 0) break; Rio_writen(forwardfd, buf, n);

if ((n = Rio_readlineb(&rio_forward, buf, MAXLINE)) == 0) break; Rio_writen(connfd, buf, n); } Close(forwardfd);}

Page 14: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Change mainint main(int argc, char **argv) { int listenfd, connfd, port, clientlen, server_port; struct sockaddr_in clientaddr; struct hostent *hp; char *haddrp, *server;

port = atoi(argv[1]); server = argv[2]; server_port = atoi(argv[3]); listenfd = Open_listenfd(port); while (1) {

clientlen = sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);

. . .

echo_forward(connfd, server, server_port); Close(connfd);

} exit(0);}

Page 15: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

L7 proxy

Different request and response (HTTP) Concurrency (next recitation) Step-by-step:

Implement sequential web proxy first (20/60 pts)

EchoClient

process

EchoServer

process

Echoproxy

process

WebBrowserprocess

WebServer

process

Webproxy

process

Page 16: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

HTTP request and response

An example of HTTP request and response More details in Tuesday’s lecture

Page 17: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

HTTP request and response[[email protected] ~]telnet www.cs.cmu.edu 80Trying 128.2.203.179...Connected to SUPERMAN.WEB.cmu.edu.Escape character is '^]'.GET / HTTP/1.1Host: www.cs.cmu.edu

HTTP/1.1 200 OKDate: Mon, 29 Nov 2004 00:29:22 GMTServer: Apache/1.3.31 (Unix) PHP/4.3.8 Transfer-Encoding: chunkedContent-Type: text/html

<HTML><HEAD><title> SCHOOL OF COMPUTER SCIENCE/Carnegie Mellon University </title></HEAD>. . . . . .

Page 18: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

HTTP requestRequest line: <method> <uri> <version>Request line: <method> <uri> <version>

Request headers: <header name>: <header data>Request headers: <header name>: <header data>

‘‘\r\n’ to mark the end of the request\r\n’ to mark the end of the request

GET / HTTP/1.1Host: www.cs.cmu.edu

<url>: Uniform Resource Locator

E.g. http://hostname:8080/path/to/the/resource

<uri>: Uniform Resource Identifier: suffix of url

E.g. /path/to/the/resources

Complete URL is used if sending request to proxy

Page 19: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

HTTP/1.1 200 OKDate: Mon, 29 Nov 2004 00:29:22 GMTServer: Apache/1.3.31 (Unix) PHP/4.3.8 Transfer-Encoding: chunkedContent-Type: text/html

<HTML><HEAD><title> SCHOOL OF COMPUTER SCIENCE/Carnegie Mellon University </title></HEAD>. . . . . .

HTTP responseResponse line: <version> <status code> <status msg>Response line: <version> <status code> <status msg>

Response headers: <header name>: <header data>Response headers: <header name>: <header data>

‘‘\r\n’\r\n’

Response body: Web pageResponse body: Web page

Page 20: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Web proxy in Lab 7

WebBrowserprocess

WebServer

process

Webproxy

process

GET http://www.cmu.edu:80/index.html HTTP/1.0

<other information>

Connects to the target web server, sends request looking like this:

GET /index.html HTTP/1.0

<other information in the original request>

Lab 7 things to-do:

parse HTTP request (1st line): extract hostname & port number

port is not necessarily specified in the request if the default number is used (80)

The web proxy simply forwards the response from the server to the browser

Page 21: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Broken pipe error

When writing to a socket whose connection has been closed prematurely at the other end e.g. click “stop” on web browser

For the first write, return normally For subsequent writes

Send SIGPIPE signal, which terminates process by default

If SIGPIPE is blocked or caught, return -1 & set EPIPE.

We don’t want to terminate the web proxy Handle this error gracefully …

Page 22: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

How to deal with broken pipe?

Block or ignore SIGPIPE signal Signal(SIGPIPE, SIG_IGN)

Ignore EPIPE error in Rio wrappers in csapp.c

Example of how we handle broken pipe in echo proxy In server main(), we block SIGPIPE signal In csapp.c, we ignore EPIPE error in Rio wrappers

Page 23: Recitation 12 (Nov. 29) Outline Socket programming Lab 7: part 1 Reminder Lab 7: Due next Thursday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays.

Some other hints

Port number

./port_for_user.pl <your andrew id> For initial debugging

use telnet; use lots of print statements Test with real Internet browser: set proxy server Use RIO package for all I/O on sockets

A lot of helper functions and wrappers in csapp.c