Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server...

23
Networking Networking 15213-S04, Recitation, Section A 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken Pipe

Transcript of Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server...

Page 1: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

NetworkingNetworking15213-S04, Recitation, Section A15213-S04, Recitation, Section A

SocketSocket

Echo Client-ServerEcho Client-Server

Extend to Echo ProxyExtend to Echo Proxy

Broken PipeBroken Pipe

Page 2: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 2 – 15-213, S’04

Networking Bibles

UNIX Network Programming, Volume 1, Second Edition: Networking APIs: Sockets and XTI

, Prentice Hall, 1998.UNIX Network Programming, Volume 2, Second Edition: Interprocess Communications, Prentice Hall, 1999.

TCP/IP Illustrated, Volume 1: The Protocols, Addison-Wesley, 1994. TCP/IP Illustrated, Volume 2: The Implementation, Addison-Wesley, 1995.TCP/IP Illustrated, Volume 3: TCP for Transactions, HTTP, NNTP, and

the UNIX Domain Protocols, Addison-Wesley, 1996.

Page 3: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 3 – 15-213, S’04

ConnectionClients and servers communicate by sending streams of bytes over

connections: point-to-point, full-duplex, and reliable

A socket is an endpoint of a connection Socket address is an IPaddress:port pair

A port is a 16-bit integer that identifies a process: well-known port: associated with some service provided by a

server (e.g., port 80 is associated with Web servers) /etc/services.global

ephemeral port: assigned automatically on client when client makes a connection request

A connection is uniquely identified by the socket addresses of its endpoints (socket pair) (cliaddr:cliport, servaddr:servport)

Page 4: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 4 – 15-213, S’04

Socket

A A socketsocket is a descriptor that lets an application is a descriptor that lets an application read/write from/to the networkread/write from/to the network

Key idea: Unix uses the same abstraction for both file I/O and network I/O

Using regular Unix read and write I/O functions

Can also be used for IPC (inter-process communication)The main difference between file I/O and socket I/O is socket

family value

Page 5: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 5 – 15-213, S’04

Defined in /usr/include/netinet/in.h

Internet-style sockets are characterized by a 32-bit IP address and a port

sockaddr_in

/* Internet address */struct in_addr { unsigned int s_addr; /* 32-bit IP address */ };

/* Internet style socket address */struct sockaddr_in { unsigned short int sin_family; /* Address family (AF_INET) */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* IP address */ unsigned char sin_zero[...]; /* Pad to sizeof

“struct sockaddr” */};

Page 6: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 6 – 15-213, S’04

Socket System Callsmust

socket() bind() listen() connect() accept() close()

socket options

ioctl() fcntl()

setsockopt() getsockopt()

gethostbyname() gethostbyaddr() getsockname()

data related

select()read() write()

send() recv()

sendto() recvfrom()

miscshutdown() socketpair() sendmsg() recvmsg()

Page 7: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 7 – 15-213, S’04

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

A Simple C/S Application -- Echo

Page 8: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 8 – 15-213, S’04

rio_readlineb

close

closeEOF

rio_readlineb

rio_writenrio_readlineb

rio_writen

listen

bind

Sequence of Socket System CallsClient Server

socket socket

acceptconnect

Connectionrequest

open_listenfd

open_clientfd

Page 9: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 9 – 15-213, S’04

#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); }

Echo Client Main Routine

Page 10: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 10 – 15-213, S’04

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

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

Page 11: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 11 – 15-213, S’04

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 12: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 12 – 15-213, S’04

Echo Server: open_listenfd

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; ... (more)

Page 13: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 13 – 15-213, S’04

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 14: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 14 – 15-213, S’04

accept()

listenfd(3)

client

1. Server blocks in accept, waiting for connection request on listening descriptor listenfd.clientfd

server

listenfd(3)

client

clientfd

server 2. Client makes connection request bycalling and blocking in connect.

listenfd(3)

client

clientfd

server

3. Server returns connfd from accept.Client returns from connect. Connection is now established between clientfd and connfd.

connectionrequest

connfd(4)

Page 15: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 15 – 15-213, S’04

Echo Server: echo

void 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 16: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 16 – 15-213, S’04

Echo Proxy

A A proxy proxy is an middle agent between a is an middle agent between a clientclient and an and an originorigin server. server. To the client, the proxy acts like a server. To the server, the proxy acts like a client.

EchoClient

process

EchoServer

process

EchoClient

process

EchoServer

process

Echoproxy

process

Page 17: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 17 – 15-213, S’04......

rio_readlineb

rio_writen

rio_readlineb

rio_writen

listen

bind

Call Sequence in Echo ProxyClient Server

socket socket

accept

connect

rio_readlineb

...

rio_readlineb

rio_writen

listen

bind

proxy

socket

accept

connect

rio_writen

Web proxy’sbenefit

Page 18: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 18 – 15-213, S’04

Changing main

int 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 19: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 19 – 15-213, S’04

echo_forward()void 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 20: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 20 – 15-213, S’04

L7 Proxy

Different request and response (HTTP)Different request and response (HTTP)

ConcurrencyConcurrency

EchoClient

process

EchoServer

process

Echoproxy

process

WebBrowserprocess

WebServer

process

Webproxy

process

Page 21: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 21 – 15-213, S’04

Broken Pipe Error

When reading or writing to a socket, whose peer has When reading or writing to a socket, whose peer has already been closedalready been closed e.g. click “stop” on web browser

SIGPIPE signal and EPIPE errnoSIGPIPE signal and EPIPE errno

For example, when writing to a broken socketFor example, when writing to a broken socket For the first write, return -1 and set EPIPE For subsequent writes,

Send SIGPIPE signal, which terminates process If the signal is blocked or handled, return -1 and set EPIPE

Page 22: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 22 – 15-213, S’04

How to deal with broken pipe?

Block SIGPIPE signalBlock SIGPIPE signal

Ignore EPIPE error in Rio wrappers of csapp.cIgnore EPIPE error in Rio wrappers of csapp.c

Example of how we handle broken pipe in echo serverExample of how we handle broken pipe in echo server In server main(), block SIGPIPE signal In csapp.c, ignore EPIPE error in Rio wrappers In echo(), deal with cases when return value is -1

Page 23: Networking 15213-S04, Recitation, Section A Socket Socket Echo Client-Server Echo Client-Server Extend to Echo Proxy Extend to Echo Proxy Broken Pipe Broken.

– 23 – 15-213, S’04

Summary

SocketSocket Connection, Socket address sockaddr_in, socket system calls

Echo Client-ServerEcho Client-Server Sequence of socket system calls

Extend to Echo ProxyExtend to Echo Proxy Combine the code from both server and client

Broken PipeBroken Pipe Block SIGPIPE and ignore EPIPE