Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Goals for Today: IPC and Sockets

CS162 • Key Idea: Communication between processes and


Operating Systems and across the world looks like File I/O
Systems Programming • Introduce Pipes and Sockets
Lecture 5 • Introduce TCP/IP Connection setup for Webserver

Abstractions 3: IPC, Pipes and Sockets


A quick programmer’s viewpoint
write(wfd, wbuf, wlen);
September 14th, 2020 Process Socket
Prof. John Kubiatowicz Socket
Process
http://cs162.eecs.Berkeley.edu
n = read(rfd, rbuf, rmax);

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.2

Recall: Creating Processes with fork() Recall: Key Unix I/O Design Concepts
• pid_t fork() – copy the current process int status; • Uniformity – Everything Is a File!
– State of original process duplicated in pid_t tcpid; – file operations, device I/O, and interprocess communication through open, read/write,
Parent and Child! … close
cpid = fork(); – Allows simple composition of programs
– Address Space (Memory), File Descriptors, etc…
if (cpid > 0) {
• Return value from fork(): pid (like an integer) mypid = getpid();
» find | grep | wc …
– When > 0: printf("[%d] parent of [%d]\n", mypid, cpid); • Open before use
tcpid = wait(&status); – Provides opportunity for access control and arbitration
» Running in (original) Parent process printf("[%d] bye %d(%d)\n",mypid,tcpid,status); – Sets up the underlying machinery, i.e., data structures
» return value is pid of new child } else if (cpid == 0) {
mypid = getpid(); • Byte-oriented
– When = 0:
printf("[%d] child\n", mypid); – Even if blocks are transferred, addressing is in bytes
» Running in new Child process exit(42); • Kernel buffered reads
– When < 0: }
… – Streaming and block devices looks the same, read blocks yielding processor to other task
» Error! Must handle somehow
• Kernel buffered writes
» Running in original process – Completion of out-going transfer decoupled from the application, allowing it to continue
• WHY FORK? • Explicit close
– (mostly true) without fork(), you cannot create new processes!
– Fork was the original mechanism for creating concurrency in UNIX (long before Linux!)
– See, however, Linux clone() which gives you more flexibility
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.3 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.4
Putting it together: web server Putting it together: web server
Kernel buffer
4. parse request 9. format reply 4. parse request reads 9. format reply
Server Server
Process request reply Process request reply
buffer buffer buffer buffer

1.network 3. kernel 10. network 1.network 3. kernel 10. network


socket copy socket 5. file 8. kernel socket copy socket 5. file 8. kernel
read() write() read() copy read() write() read() copy

Kernel wait syscall RTU syscall syscall RTU Kernel syscall RTU syscall syscall RTU
wait
11. kernel copy 11. kernel copy
from user buffer from user buffer
to network buffer to network buffer
interrupt interrupt
interrupt 2. copy arriving 12. format outgoing 6. disk interrupt 2. copy arriving 12. format outgoing 6. disk
packet (DMA) 7. disk data packet (DMA) 7. disk data
packet and DMA request packet and DMA request
(DMA) (DMA)

Hardware Hardware
Network Network
Disk interface Disk interface
interface interface

Request Reply Today: Network Communication Request Reply Today: Network Communication
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.5 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.6

Putting it together: web server Recall: C High-Level File API – Streams


Kernel buffer • Operates on “streams” – unformatted sequences of bytes (wither text or binary data), with
4. parse request write a position:
Server 9. format reply
Process request reply
buffer buffer #include <stdio.h>
1.network 3. kernel 10. network FILE *fopen( const char *filename, const char *mode );
socket copy socket 5. file 8. kernel int fclose( FILE *fp );
read() write() read() copy
syscall RTU syscall syscall RTU Mode Text Binary Descriptions
Kernel
11. kernel copy r rb Open existing file for reading
from user buffer w wb Open for writing; created if does not exist
to network buffer
a ab Open for appending; created if does not exist
interrupt
interrupt 2. copy arriving 12. format outgoing 6. disk r+ rb+ Open existing file for reading & writing.
packet (DMA) 7. disk data
packet and DMA request w+ wb+ Open for reading & writing; truncated to zero if exists, create otherwise
(DMA)
a+ ab+ Open for reading & writing. Created if does not exist. Read from beginning, write
as append
Hardware
Network
Disk interface
• Open stream represented by pointer to a FILE data structure
interface
– Error reported by returning a NULL pointer
– Pointer used in subsequent operations on the stream
Request Reply
– Data buffered in user space
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.7 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.8
Recall: Low-Level File I/O: The RAW system-call interface Recall: Representation of a Process (inside kernel!)
#include <fcntl.h> Process
#include <unistd.h>
#include <sys/types.h> Suppose that we execute
Thread’s
Regs open(“foo.txt”)
int open (const char *filename, int flags [, mode_t mode]) Address
… Space and that the result is 3
int creat (const char *filename, mode_t mode)
int close (int filedes) (Memory)
User Space
Bit vector of:
Bit vector of Permission Bits:
• Access modes (Rd, Wr, …) Kernel Space
• User|Group|Other X R|W|X
• Open Flags (Create, …) File Descriptors Open File Description
• Operating modes (Appends, …)
3
Not shown: File: foo.txt
• Integer return from open() is a file descriptor Initially contains 0, Position: 0
1, and 2 (stdin,
– Error indicated by return < 0: the global errno variable set with error stdout, stderr)
– File Descriptor used in subsequent operations on the file
Each open file has file description
• Streams (opened with fopen()) have a file descriptor inside of them!
– Retrievable with fileno(FILE *stream)  internal file descriptor Descriptor Table provides redirection

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.9 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.10

Recall: What Happens on fork()? Recall standard file descriptors: 0, 1, 2


Process 1 Process 2 Parent Process Child Process

Thread’s Thread’s Thread’s Thread’s


Regs Address Regs Address Regs Address Regs Address
… Space … Space … Space … Space
(Memory) (Memory) (Memory) (Memory)
User Space User Space
Kernel Space Kernel Space Terminal Emulator
File Descriptors File Descriptors File Descriptors File Descriptors
Open File Description
3 3 0 0
Not shown: File: foo.txt 1 1
Initially contains 0, Position: 100 2 2
1, and 2 (stdin,
stdout, stderr)

• After fork(): 0: stdout (terminal output)


– File Descriptors copied: child has same descriptor table as parent! 1: stderr (error output)
2: stdin (terminal input)
– File Descriptions shared: child and parent can both manipulate/change open files
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.11 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.12
Administrivia Today: Communication Between Processes
• Homework 1 due Wednesday • What if processes wish to communicate with one another?
• Project 1 in full swing! – Why? Shared Task, Cooperative Venture with Security Implications
– We expect that your design document will give intuitions behind your designs, not just a
dump of pseudo-code • Process Abstraction Designed to Discourage Inter-Process Communication!
– Think of this you are in a company and your TA is you manager – Prevent one process from interfering with/stealing information from another
• Should be attending your permanent discussion section! • So, must do something special (and agreed upon by both processes)
– Remember to turn on your camera in Zoom
– Must “Punch Hole” in security
– Discussion section attendance is mandatory
• Midterm 1: October 1st, 5-7PM (Three weeks from tomorrow!) • This is called “Interprocess Communication” (or IPC)
– We understand that this partially conflicts with CS170, but those of you in CS170 can start
that exam after 7PM (according to CS170 staff)
– Video Proctored, No curve, Use of computer to answer questions
– More details as we get closer to exam
• Start Planning on how your group will collaborate on projects! Hello!
– Virtual Coffee Hours with your group (with camera)
– Regular Brainstorming meetings? Hi!
– Try to meet multiple times a week
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.13 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.14

Recall: Processes Protected from each other Communication Between Processes


Data 2 • Producer (writer) and consumer (reader) may be distinct processes
Code Code
Stack 1 – Potentially separated in time
Data Data
Heap 1
– How to allow selective communication?
Heap Heap
Code 1
Stack Stack • Simple option: use a file!
Stack 2
Prog 1 Prog 2 – We have already shown how parents and children share file descriptions:
Virtual Data 1 Virtual
Address Heap 2 Address write(wfd, wbuf, wlen);
Space 1 Space 2
Process Persistent Process
Code 2
A Storage B
OS code
n = read(rfd, rbuf, rmax);
Translation Map 1 OS data Translation Map 2
OS heap &
• Why might this be wasteful?
Stacks – Very expensive if you only want transient communication (non-persistent)
Physical Address Space
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.15 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.16
Shared Memory: Better Option?
Topic for another day! Communication Between Processes (Another Option)
Data 2 • Suppose we ask Kernel to help?
Code Code
Stack 1 – Consider an in-memory queue
Data Data – Accessed via system calls (for security reasons):
Heap 1
Shared Shared
Code 1 write(wfd, wbuf, wlen);
Heap Heap
Stack 2 Process In-Memory Process
Stack Stack A Queue B
Data 1
Prog 1 Prog 2 n = read(rfd, rbuf, rmax);
Heap 2
Virtual Virtual • Data written by A is held in memory until B reads it
Address Code 2 Address – Same interface as we use for files!
Space 1 Space 2
Shared – Internally more efficient, since nothing goes to disk
OS code • Some questions:
Translation Map 1 OS data Translation Map 2 – How to set up?
OS heap & – What if A generates data faster than B can consume it?
Stacks
– What if B consumes data faster than A can produce it?
9/14/20
Physical Address Space
Kubiatowicz CS162 © UCB Fall 2020 Lec 5.17 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.18

One example of this pattern: POSIX/Unix PIPE Single-Process Pipe Example


write(wfd, wbuf, wlen); #include <unistd.h>
int main(int argc, char *argv[])
Process Process
UNIX Pipe {
A B
char *msg = "Message in a pipe.\n";
n = read(rfd, rbuf, rmax); char buf[BUFSIZE];
int pipe_fd[2];
• Memory Buffer is finite: if (pipe(pipe_fd) == ‐1) {
– If producer (A) tries to write when buffer full, it blocks (Put sleep until space) fprintf (stderr, "Pipe failed.\n"); return EXIT_FAILURE;
– If consumer (B) tries to read when buffer empty, it blocks (Put to sleep until data) }
ssize_t writelen = write(pipe_fd[1], msg, strlen(msg)+1);
printf("Sent: %s [%ld, %ld]\n", msg, strlen(msg)+1, writelen);
int pipe(int fileds[2]);
– Allocates two new file descriptors in the process ssize_t readlen = read(pipe_fd[0], buf, BUFSIZE);
printf("Rcvd: %s [%ld]\n", msg, readlen);
– Writes to fileds[1] read from fileds[0]
– Implemented as a fixed‐size queue close(pipe_fd[0]);
close(pipe_fd[1]);
}
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.19 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.20
Pipes Between Processes Inter-Process Communication (IPC): Parent  Child
Parent Process Child Process // continuing from earlier
pipe(…) pid_t pid = fork();
fork() Thread’s Thread’s if (pid < 0) {
Regs Address Regs Address fprintf (stderr, "Fork failed.\n");
… Space … Space
return EXIT_FAILURE;
(Memory) (Memory)
}
User Space if (pid != 0) {
Kernel Space ssize_t writelen = write(pipe_fd[1], msg, msglen);
File Descriptors File Descriptors printf("Parent: %s [%ld, %ld]\n", msg, msglen, writelen);
3 3 close(pipe_fd[0]);
4 In 4
Pipe } else {
ssize_t readlen = read(pipe_fd[0], buf, BUFSIZE);
Out
printf("Child Rcvd: %s [%ld]\n", msg, readlen);
close(pipe_fd[1]);
}

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.21 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.22

Channel from Parent  Child Instead: Channel from Child  Parent


Parent Process Child Process Parent Process Child Process
pipe(…) pipe(…)
fork() Thread’s Thread’s fork() Thread’s Thread’s
close(3) Regs Address Regs Address close(4) Regs Address Regs Address
… Space … Space
close(4) … Space … Space
close(3)
(Memory) (Memory) (Memory) (Memory)
User Space User Space
Kernel Space File Descriptors File Descriptors
Kernel Space File Descriptors File Descriptors
3 3 3 3
4 In 4 4 In 4
Pipe Pipe

Out Out

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.23 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.24
When do we get EOF on a pipe? EOF on a Pipe
• After last “write” descriptor is closed, pipe is effectively closed: Process 1 Process 2
– Reads return only “EOF” pipe(…)
• After last “read” descriptor is closed, writes generate SIGPIPE signals: fork() Thread’s Thread’s

– If process ignores, then the write fails with an “EPIPE” error close(3) Regs Address Regs Address
… Space … Space
close(4)
close(4)
(Memory) (Memory)
User Space
Kernel Space File Descriptors File Descriptors
3
4 In
Pipe

Out

EOF

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.25 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.26

Once we have communication, we need a protocol Examples of Protocols in Human Interaction


• A protocol is an agreement on how to communicate
• Includes 1. Telephone
– Syntax: how a communication is specified & structured 2. (Pick up / open up the phone)
» Format, order messages are sent and received 3. Listen for a dial tone / see that you have service
– Semantics: what a communication means 4. Dial
5. Should hear ringing …
» Actions taken when transmitting, receiving, or when a timer expires
6. Callee: “Hello?”
• Described formally by a state machine 7. Caller: “Hi, it’s John….”
– Often represented as a message transaction diagram Or: “Hi, it’s me” (what’s that about?)
8. Caller: “Hey, do you think … blah blah blah …” pause
• In fact, across network may need a way to translate between different
representations for numbers, strings, etc
9. Callee: “Yeah, blah blah blah …”
– Such translation typically part of a Remote Procedure Call (RPC) facility pause
– Don’t worry about this now, but it is clearly part of the protocol 10. Caller: Bye
11. Callee: Bye
12. Hang up

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.27 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.28
Web Server Client-Server Protocols: Cross-Network IPC

Client 1
Request
Client 2 Server

***
Reply

Client Web Server Client n

• Many clients accessing a common server


• File servers, www, FTP, databases

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.29 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.30

Client-Server Communication What is a Network Connection?


• Client is “sometimes on” • Server is “always on” • Bidirectional stream of bytes between two processes on possibly different
machines
– Sends the server requests for – Services requests from many
services when interested clients – For now, we are discussing “TCP Connections”
– E.g., Web browser on laptop/phone – E.g., Web server for www.cnn.com
– Doesn’t communicate directly with – Doesn’t initiate contact with clients • Abstractly, a connection between two endpoints A and B consists of:
other clients – Needs a fixed, well-known address – A queue (bounded buffer) for data sent from A to B
– Needs to know server’s address – A queue (bounded buffer) for data sent from B to A
GET /index.html

“Site under construction”

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.31 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.32
The Socket Abstraction: Endpoint for Communication Sockets: More Details
• Key Idea: Communication across the world looks like File I/O • Socket: An abstraction for one endpoint of a network connection
write(wfd, wbuf, wlen); – Another mechanism for inter-process communication
– Most operating systems (Linux, Mac OS X, Windows) provide this, even if they
Process Socket don’t copy rest of UNIX I/O
Process – Standardized by POSIX
Socket

n = read(rfd, rbuf, rmax); • First introduced in 4.2 BSD (Berkeley Standard Distribution) Unix
– This release had some huge benefits (and excitement from potential users)
– Runners waiting at release time to get release on tape and take to businesses
• Sockets: Endpoint for Communication
– Queues to temporarily hold results • Same abstraction for any kind of network
– Local (within same machine)
• Connection: Two Sockets Connected Over the network  IPC over network!
– The Internet (TCP/IP, UDP/IP)
– How to open()?
– Things “no one” uses anymore (OSI, Appletalk, IPX, …)
– What is the namespace?
– How are they connected in time?

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.33 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.34

Sockets: More Details Simple Example: Echo Server


• Looks just like a file with a file descriptor
– Corresponds to a network connection (two queues)
– write adds to output queue (queue of data destined for other side)
– read removes from it input queue (queue of data destined for this side)
– Some operations do not work, e.g. lseek
“hello, world”

• How can we use sockets to support real applications?


– A bidirectional byte stream isn’t useful on its own… “hello, world”
– May need messaging facility to partition stream into chunks
– May need RPC facility to translate one environment to another and provide Client Web Server
the abstraction of a function call over the network

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.35 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.36
Simple Example: Echo Server Echo client-server example
void client(int sockfd) {
Client (issues requests) Server (services requests) int n;
fgets(sndbuf,bufsize,stdin); char sndbuf[MAXIN]; char rcvbuf[MAXOUT];
while (1) {
write(sockfd,sndbuf,strlen(sndbuf)+1); n = read(sockfd,reqbuf,…); fgets(sndbuf,MAXIN,stdin); /* prompt */
write(sockfd, sndbuf, strlen(sndbuf)+1); /* send (including null terminator) */
wait memset(rcvbuf,0,MAXOUT); /* clear */
n=read(sockfd, rcvbuf, MAXOUT); /* receive */
write(STDOUT_FILENO, rcvbuf, n); /* echo */
}
n = read(sockfd,rcvbuf, …);
Server print
Client
wait Socket Socket
write(sockfd,reqbuf,…); void server(int consockfd) {
char reqbuf[MAXREQ];
int n;
while (1) {
memset(reqbuf,0, MAXREQ);
len = read(consockfd,reqbuf,MAXREQ); /* Recv */
if (n <= 0) return;
write(STDOUT_FILENO, reqbuf, n);
print write(consockfd, reqbuf, n); /* echo*/
}
}
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.37 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.38

What Assumptions are we Making? Socket Creation


• Reliable • File systems provide a collection of permanent objects in a structured name space:
– Write to a file => Read it back. Nothing is lost. – Processes open, read/write/close them
– Write to a (TCP) socket => Read from the other side, same. – Files exist independently of processes
– Easy to name what file to open()
– Like pipes
• Pipes: one-way communication between processes on same (physical) machine
• In order (sequential stream)
– Single queue
– Write X then write Y => read gets X then read gets Y
– Created transiently by a call to pipe()
– Passed from parent to children (descriptors inherited from parent process)
• When ready? • Sockets: two-way communication between processes on same or different
– File read gets whatever is there at the time. machine
– Assumes writing already took place – Two queues (one in each direction)
– Blocks if nothing has arrived yet – Processes can be on separate machines: no common ancestor
– How do we name the objects we are opening?
– Like pipes!
– How do these completely independent programs know that the other wants to “talk” to
them?
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.39 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.40
Namespaces for Communication over IP Connection Setup over TCP/IP
• Hostname
Server
– www.eecs.berkeley.edu
Socket
• IP address
– 128.32.244.172 (IPv4, 32-bit Integer) new
– 2607:f140:0:81::f (IPv6, 128-bit Integer) socket
Connection
• Port Number socket connection
connection
Client socket
– 0-1023 are “well known” or “system” ports Server
» Superuser privileges to bind to one
• Special kind of socket: server socket
– 1024 – 49151 are “registered” ports (registry) – Has file descriptor
» Assigned by IANA for specific services – Can’t read or write
– 49152–65535 (215+214 to 216−1) are “dynamic” or “private” • Two operations:
» Automatically allocated as “ephemeral ports” 1. listen(): Start allowing clients to connect
2. accept(): Create a new socket for a particular client

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.41 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.42

Connection Setup over TCP/IP Sockets in concept


Client Server
Create Server Socket
Server
Socket Bind it to an Address
Create Client Socket
(host:port)
new
socket Connect it to server (host:port) Listen for Connection
Connection
socket connection
Client socket Accept syscall()
Server
Connection Socket Connection Socket
• 5-Tuple identifies each • Often, Client Port “randomly” write request read request
connection: assigned
1. Source IP Address read response write response
– Done by OS during client socket setup
2. Destination IP Address
3. Source Port Number
• Server Port often “well known”
Close Client Socket Close Connection Socket
4. Destination Port Number – 80 (web), 443 (secure web), 25
(sendmail), etc
5. Protocol (always TCP here)
– Well-known ports from 0—1023 Close Server Socket
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.43 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.44
Client Protocol Server Protocol (v1)
char *host_name, *port_name; // Create socket to listen for client connections
char *port_name;
// Create a socket struct addrinfo *server = setup_address(port_name);
struct addrinfo *server = lookup_host(host_name, port_name); int server_socket = socket(server‐>ai_family,
int sock_fd = socket(server‐>ai_family, server‐>ai_socktype, server‐>ai_socktype, server‐>ai_protocol);
// Bind socket to specific port
server‐>ai_protocol);
bind(server_socket, server‐>ai_addr, server‐>ai_addrlen);
// Start listening for new client connections
// Connect to specified host and port listen(server_socket, MAX_QUEUE);
connect(sock_fd, server‐>ai_addr, server‐>ai_addrlen);
while (1) {
// Carry out Client‐Server protocol // Accept a new client connection, obtaining a new socket
run_client(sock_fd); int conn_socket = accept(server_socket, NULL, NULL);
serve_client(conn_socket);
/* Clean up on termination */ close(conn_socket);
close(sock_fd); }
close(server_socket);

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.45 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.46

How Could the Server Protect Itself? Sockets With Protection (each connection has own process)
Client Server
• Handle each connection in a separate process Create Server Socket

Create Client Socket Bind it to an Address


(host:port)

Connect it to server (host:port) Listen for Connection

Accept syscall()

Connection Socket Connection Socket


Child Parent
Close Listen Socket Close Connection
write request read request
Socket
read response write response
Wait for child
Close Connection
Close Client Socket
Socket
Close Server Socket
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.47 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.48
Server Protocol (v2) Concurrent Server
// Socket setup code elided…
• So far, in the server:
while (1) {
// Accept a new client connection, obtaining a new socket – Listen will queue requests
int conn_socket = accept(server_socket, NULL, NULL); – Buffering present elsewhere
pid_t pid = fork(); – But server waits for each connection to terminate before servicing the next
if (pid == 0) {
close(server_socket);
serve_client(conn_socket); • A concurrent server can handle and service a new connection before the
close(conn_socket); previous client disconnects
exit(0);
} else {
close(conn_socket);
wait(NULL);
}
}
close(server_socket);

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.49 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.50

Sockets With Protection and Concurrency Server Protocol (v3)


Client Server // Socket setup code elided…
Create Server Socket while (1) {
// Accept a new client connection, obtaining a new socket
Create Client Socket Bind it to an Address
(host:port)
int conn_socket = accept(server_socket, NULL, NULL);
pid_t pid = fork();
Connect it to server (host:port) Listen for Connection
if (pid == 0) {
close(server_socket);
Accept syscall() serve_client(conn_socket);
close(conn_socket);
Connection Socket Connection Socket exit(0);
Child Parent } else {
Close Listen Socket Close Connection close(conn_socket);
write request read request
Socket //wait(NULL);
read response write response }
}
Close Connection Close Server Socket close(server_socket);
Close Client Socket
Socket

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.51 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.52
Server Address: Itself Client: Getting the Server Address
struct addrinfo *setup_address(char *port) { struct addrinfo *lookup_host(char *host_name, char *port) {
struct addrinfo *server; struct addrinfo *server;
struct addrinfo hints;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC;
hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; int rv = getaddrinfo(host_name, port_name,
&hints, &server);
getaddrinfo(NULL, port, &hints, &server);
if (rv != 0) {
return server; printf("getaddrinfo failed: %s\n", gai_strerror(rv));
} return NULL;
}
• Accepts any connections on the specified port return server;
}

9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.53 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.54

Concurrent Server without Protection Sockets with Concurrency, without Protection


Client Server
• Spawn a new thread to handle each connection Create Server Socket
• Main thread initiates new client connections without waiting for previously
spawned threads Create Client Socket Bind it to an Address
(host:port)
• Why give up the protection of separate processes?
– More efficient to create new threads Connect it to server (host:port) Listen for Connection
– More efficient to switch between threads
Accept syscall()

Connection Socket Connection Socket


pthread_create
Spawned Thread
write request read request Main Thread
read response write response

Close Connection
Close Client Socket Close Server Socket
Socket
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.55 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.56
Thread Pools Conclusion
• Problem with previous version: Unbounded Threads • Interprocess Communication (IPC)
– When web-site becomes too popular – throughput sinks – Communication facility between protected environments (i.e. processes)
• Instead, allocate a bounded “pool” of worker threads, representing the
maximum level of multiprogramming • Pipes are an abstraction of a single queue
– One end write-only, another end read-only
– Used for communication between multiple processes on one machine

queue
Master
– File descriptors obtained via inheritance
Thread

• Sockets are an abstraction of two queues, one in each direction


Thread Pool – Can read or write to either end
master() { worker(queue) { – Used for communication between multiple processes on different machines
allocThreads(worker,queue); while(TRUE) { – File descriptors obtained via socket/bind/connect/listen/accept
while(TRUE) { con=Dequeue(queue); – Inheritance of file descriptors on fork() facilitates handling each connection in a separate
con=AcceptCon(); if (con==null) process
Enqueue(queue,con); sleepOn(queue);
wakeUp(queue); else
} ServiceWebPage(con); • Both support read/write system calls, just like File I/O
} }
}
9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.57 9/14/20 Kubiatowicz CS162 © UCB Fall 2020 Lec 5.58

You might also like