Interprocess Communication Interprocess Communication
Interprocess Communication Interprocess Communication
Interprocess Communication
Batch‐processing systems
Centralized system based on mainframe
Multiterminal Systems
Main Events
• 1969: ARPANET
• Early 1980s: TCP/IP
• 1980: Ethernet
• 1985: Token Ring, FDDI
• 1991: WWW
1991: WWW
• 1994: Yahoo
• 1998: Google
Sharing resources
• Data
• Computation
Sharing resources
Socket
What is a socket?
• An interface between application and network
– The application creates a socket
Th li ti t k t
– The socket type dictates the style of
communication
• reliable vs. best effort
• connection‐oriented vs. connectionless
• Once configured the application can
– pass data to the socket for network transmission
– receive data from the socket (transmitted through
the network by some other host)
8
Two essential types of sockets
• SOCK_STREAM • SOCK_DGRAM
– a.k.a. TCP – a.k.a. UDP
– reliable delivery
li bl d li – unreliable delivery
– in‐order guaranteed – no order guarantees
– connection‐oriented – no notion of “connection” – app
– bidirectional indicates dest. for each packet
– can send or receive
App
App D1
3 2
1
socket Dest.
3 2
1
socket D2
D3
9
Socket Creation in C: socket()
10
Ports
• Each host has 65,536
ports Port 0
Port 0
• Some ports are Port 1
reserved for specific
f p f
apps Port 65535
– 20,21: FTP
– 23: Telnet A socket provides an interface to send data
to/from the network through a port
– 80: HTTP
– see RFC 1700 (about
see RFC 1700 (about
2000 ports are
reserved)
11
Addresses, Ports and Sockets
• Like apartments and mailboxes
– You are the application
You are the application
– Your apartment building address is the address
– Your mailbox is the port
Your mailbox is the port
– The post‐office is the network
– The socket is the key that gives you access to the right
mailbox (one difference: assume outgoing mail is
placed by you in your mailbox)
• Q: How do you choose which port a socket
connects to?
12
The bind() function
• associates and (can exclusively) reserves a port for
use by the socket
use by the socket
• int status = bind(sockid, &addrport, size);
– status: error status = 1 if bind failed
status: error status, = ‐1 if bind failed
– sockid: integer, socket descriptor
– addrport: struct
addrport: struct sockaddr, the (IP) address and port of
sockaddr, the (IP) address and port of
the machine (address usually set to INADDR_ANY –
chooses a local address)
h i (i b ) f h dd
– size: the size (in bytes) of the addrport
i t structure
13
Connection Setup (SOCK_STREAM)
• Recall: no connection setup for SOCK_DGRAM
• A connection occurs between two kinds of
A ti b t t ki d f
participants
– passive:
passive: waits for an active participant to request
waits for an active participant to request
connection
– active: initiates connection request to passive side
• Once connection is established, passive and active
participants are “similar”
– both can send & receive data
– either can terminate the connection
14
Connection setup cont’d
• Passive participant • Active participant
p p
– step 1: listen (for incoming
requests)
– step 2: request & establish
– step 3: accept (a request)
connection
– step 4: data transfer
• The accepted connection – step 4: data transfer
is on a new socket
Passive Participant
• The old socket continues
to listen for other active a‐sock‐1 l‐sock a‐sock‐2
participants
• Why?
socket socket
k t
Active 1 Active 2
15
Connection setup: listen & accept
• Called by passive participant
• int status = listen(sock, queuelen);
– status: 0 if listening, ‐1 if error
– sock: integer, socket descriptor
– queuelen: integer, # of active participants that can “wait” for a
connection
– listen is non‐blocking: returns immediately
• int s = accept(sock, &name, &namelen);
– g , (
s: integer, the new socket (used for data‐transfer))
– sock: integer, the orig. socket (being listened on)
– name: struct sockaddr, address of the active participant
– namelen: sizeof(name): value/result parameter
• must be set appropriately before call
b i l b f ll
• adjusted by OS upon return
– accept is blocking: waits for connection before returning
connect call
17
Sending / Receiving Data
• With a connection (SOCK_STREAM):
– int count = send(sock
send(sock, &buf
&buf, len
len, flags);
• count: # bytes transmitted (‐1 if error)
• buf: char[], buffer to be transmitted
• l
len: integer, length of buffer (in bytes) to transmit
• flags: integer, special options, usually just 0
– int count = recv(sock, &buf, len, flags);
• count: # bytes received (‐1 if error)
• buf: void[], stores received bytes
• len # b t i d
len: # bytes received
• flags: integer, special options, usually just 0
– Calls are blockingg [[returns only after data is sent
y
(to socket buf) / received]
18
Sending / Receiving Data (cont’d)
• Without a connection (SOCK_DGRAM):
– int count = sendto(sock, &buf, len, flags, &addr,
addrlen);
• count,
t sock,
k buf,
b f len,
l fl
flags: same as send
d
• addr: struct sockaddr, address of the destination
• addrlen: sizeof(addr)
addrlen: sizeof(addr)
– int count = recvfrom(sock, &buf, len, flags,
&addr &addrlen);
&addr,
• count, sock, buf, len, flags: same as recv
• name: struct sockaddr, address of the source
• namelen: sizeof(name): value/result parameter
19
close
• When finished using a socket, the socket
should be closed:
h ld b l d
• status = close(s);
– status: 0 if successful, ‐1 if error
– s: the file descriptor (socket being closed)
• Closing a socket
– closes a connection (for SOCK_STREAM)
closes a connection (for SOCK STREAM)
– frees up the port used by the socket
20
Socket communication
The struct sockaddr
• The generic:
struct sockaddr {
• The Internet‐specific:
p
u_short sa_family; struct sockaddr_in {
char sa_data[14]; short sin_family;
}; u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
– sa_family };
• specifies which address – sin_family = AF_INET
family is being used – sin_port: port # (0‐65535)
• determines how the – sin_addr: IP‐address
remaining 14 bytes are – sin_zero: unused
used
22
Address and port byte‐ordering
• Address and port are stored as integers
– u_short sin_port; (16 bit)
u short sin port; (16 bit) struct in_addr
in addr {
– in_addr sin_addr; (32 bit) u_long s_addr;
};
Problem:
different machines / OS’s use different word orderings
• little‐endian: lower bytes first
• big‐endian: higher bytes first
these machines may communicate with one another over the network
Big‐Endian
machine Little‐Endian
machine 12.40.119.128
128.119.40.12
• Defs:
– Host Byte‐Ordering: the byte ordering used by
H t B t O d i th b t d i db
a host (big or little)
– Network Byte
Network Byte‐Ordering:
Ordering: the byte ordering used
the byte ordering used
by the network – always big‐endian
• Any words sent through the network should be converted
to Network Byte‐Order prior to transmission (and back to
Host Byte‐Order once received)
24
UNIX’s byte‐ordering funcs
• u_long
g htonl(u
( _long
g x);
); • u_long
g ntohl(u
( _long
g x);
);
• u_short htons(u_short x); • u_short ntohs(u_short x);
On big‐endian machines, these routines do nothing
On little‐endian machines, they reverse the byte order
Big‐Endian
machine Little‐Endian
128 119 40 12 12 128.119.40.12
40 119 128
128.119.40.12 machine
ntohl
128 119 40 12 128 119 40 12
25
Dealing with blocking calls
• Many of the functions we saw block until a certain event
– until a connection comes in
accept: until a connection comes in
accept:
– connect: until the connection is established
– recv, recvfrom: until a packet (of data) is received
– send, til d t i h di t k t’ b ff
d sendto: until data is pushed into socket’s buffer
dt
• For simple programs, blocking is convenient
• What about more complex programs?
What about more complex programs?
– multiple connections
– simultaneous sends and receives
– simultaneously doing non‐networking processing
i l l d i ki i
26
Dealing w/ blocking (cont’d)
• Options:
– create
create multi
multi‐process
process or multi
or multi‐threaded
threaded code
code
– turn off the blocking feature (e.g., using the fcntl file‐descriptor
control function)
– use the select
use the select function call.
function call
• What does select do?
– can be permanent blocking, time‐limited blocking or non‐blocking
– input: a set of file‐descriptors
– output: info on the file‐descriptors’ status
– i.e., can identify sockets that are “ready
i.e., can identify sockets that are ready for use
for use”:: calls involving that
calls involving that
socket will return immediately
27
select function call
28
To be used with select:
• Recall select uses a structure, struct fd_set
– it is just a bit‐vector
it is just a bit‐vector
– if bit i is set in [readfds, writefds, exceptfds],
select will check if file descriptor (i.e. socket) i is
ready for [reading, writing, exception]
d f [ di ii i ]
• Before calling select:
FD ZERO(&fdvar): clears the structure
– FD_ZERO(&fdvar): clears the structure
– FD_SET(i, &fdvar): to check file desc. i
• After calling select:
After calling select:
– int FD_ISSET(i, &fdvar): boolean returns TRUE
iff i is “ready”
29
Other useful functions
• bzero(char* c, int n): 0’s n bytes starting at c
• gethostname(char *name,name, int len): gets the name of the
gets the name of the
current host
• gethostbyaddr(char *addr, int len, int type): converts IP
hostname to structure containing long integer
hostname to structure containing long integer
• inet_addr(const char *cp): converts dotted‐decimal char‐
string to long integer
• inet_ntoa(const struct in_addr in): converts long to dotted‐
decimal notation
• Warning: check function assumptions about byte‐ordering
(host or network). Often, they assume parameters / return
solutions in network byte‐order
solutions in network byte‐order
30