Socket

advertisement
CS 3214
Computer Systems
Lecture 24
Godmar Back
Announcements
• Project 5 due Dec 8
• Exercise 10 handed out
• Exercise 11 coming before Thanksgiving
CS 3214 Fall 2010
Some of these slides are substantially derived from slides provided by
Jim Kurose & Keith Ross. Copyright on this material is held by Kurose
& Ross. Used with permission. The textbook is Computer Networking:
A Top Down Approach Featuring the Internet Jim Kurose, Keith Ross,
Addison-Wesley, July 2004
Part 2
NETWORKING
CS 3214 Fall 2010
Socket Programming
UDP & TCP
Network Socket Programming
Socket: (narrow definition:) a door between
application process and end-end-transport
protocol (UDP or TCP)
controlled by
application
developer
controlled by
operating
system
process
process
socket
Stack w/
buffers,
variables
internet
socket
Stack w/
buffers,
variables
host or
server
host or
server
CS 3214 Fall 2010
controlled by
application
developer
controlled by
operating
system
Socket Programming
socket
Socket API
• introduced in BSD 4.1
UNIX, 1981
• explicitly created,
used, released by
apps
• used for both local and
remote communication
CS 3214 Fall 2010
a host-local,
application-created,
OS-controlled interface
(a “door”) into which
application process can
both send and
receive messages to/from
another application
process
BSD Socket API
• API – Application Programming Interface
– Provides access to services
– Specified in C language
– Implemented on many platforms in one way or the other
• (Windows: WinSock2, CSocket MFC classes for BSD-like look)
• Sockets (in Unix) are file descriptors
– General idea: writing to the socket is sending data to network,
reading from socket is receiving data
– Good because read(2), write(2), close(2) and others (select(2),
poll(2), ioctl(2), SIGIO, fcntl(2)) can be reused
– Bad because suggest orthogonality if where there is none
• Other languages provide separate mapping, often thin
veneers over BSD sockets (e.g., java.net.Socket)
CS 3214 Fall 2010
Addressing
• For UDP/IP or TCP/IP socket communication, generally
need 4 parameters:
–
–
–
–
Source Identifier (32-bit IP Address)
Source Port (16-bit)
Destination Identifier (32-bit IP Address)
Destination Port (16-bit)
• Notice that the relationship of “local” and “remote” (also
called “peer”) to source/destination depends on direction
of communication
• Note:
– UDP uses only Destination (IP+Port) for demultiplexing
– TCP uses Source + Destination
• (quadruple: Src IP, Src Port, Dst IP, Dest Port)
CS 3214 Fall 2010
223.1.1.2
Addressing in IP
• IP address
interfaces, not hosts
• Sets of interfaces
form subnets
223.1.1.1
223.1.1.4
223.1.1.3
223.1.9.2
223.1.7.1
– Subnets share
common prefix
• Route to CIDR-ized
subnet addresses
223.1.9.1
223.1.8.1
– a.b.c.d/x
• Within subnet,
reach
223.1.2.1
destination directly
223.1.7.2
223.1.8.2
223.1.2.6
223.1.3.27
223.1.2.2
CS 3214 Fall 2010
223.1.3.1
223.1.3.2
Internet
R1
Ethernet
LAN 1
60 Machines
191.23.25.193
PPP Link 2
191.23.25.192/30
191.23.25.197
Subnet address:
191.23.25.128/26
Default gateway:
191.23.25.129
R2
191.23.25.194
PPP Link 1
191.23.25.129
191.23.25.196/30
191.23.25.198
R3
Ethernet
LAN 2
120 Machines
191.23.25.1
Subnet address:
191.23.25.0/25
Default gateway:
191.23.25.1
CS 3214 Fall 2010
UDP Sockets: Overview
socket()
socket()
connect()
bind()
(optional)
send()
recv()
acts like
acts like
sendto()
recvfrom()
recvfrom()
sendto()
Client
Server
CS 3214 Fall 2010
socket(2)
int socket(int domain, int type, int protocol)
• domain: PF_INET, PF_UNIX, PF_INET6, ….
• type: SOCK_DGRAM (for UDP), SOCK_STREAM (for TCP),
…
• protocol:
– 0 for Unspecified (or IPPROTO_UDP or IPPROTO_TCP)
• returns integer file descriptor
– entirely between process and OS – no network actions involved
whatsoever
• man pages: ip(7), udp(7), tcp(7), socket(2), socket (7), unix(7)
– type “man 2 socket”, “man 7 socket”
CS 3214 Fall 2010
bind(2)
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
• sockfd: return by socket()
• my_addr: “socket address”
• addrlen
– length of address (address is variable-sized data
structure)
• “binds” socket to (local) address specified
– This affects network protocol namespace, but no
information is transmitted over network
– Typically: one socket per port, exception: multicast
CS 3214 Fall 2010
How are addresses represented?
struct sockaddr { /* GENERIC TYPE, should be “abstract” */
sa_family_t sa_family;
/* address family */
char sa_data[14];
/* address data */
};
/* This is the concrete “subtype” for IPv4 */
struct sockaddr_in {
sa_family_t
sin_family;
/* address family: AF_INET */
u_int16_t
sin_port;
/* port in network byte order */
struct in_addr sin_addr;
/* internet address */
};
/* Internet IPv4 address. */
struct in_addr {
u_int32_t
s_addr;
};
/* address in network byte order */
CS 3214 Fall 2010
More on bind(2)
• Address specified is the “local” address
– Which is destination for receive and source for sends.
• sin_addr.s_addr useful for “multi-homed” hosts,
otherwise use INADDR_ANY
• sin_port may be zero if any port would do
– Use getsockname() to retrieve assigned port
• s_addr and sin_port are specified in network
byte order
– This convention holds throughout socket API
• getaddrinfo() prepares suitable structs
CS 3214 Fall 2010
Common Pitfalls (1)
• Network vs. Host Byte order
– Network order is big endian, most-significant byte first
– Host order may be either big or little: little endian on
x86
– Use ntohs(), ntohl(), htons(), htonl() to convert 16-bit
(“short”) and 32-bit (“long”) values portably
– Never convert addresses/ports in sockaddr_in
structures in place
• Not as much an issue in languages that hide
data representation (e.g., Java)
CS 3214 Fall 2010
Common Pitfalls (2)
• Pay attention to “length” parameters
• Example
int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
• namelen here is not OUT, its INOUT
– aka value-result
– You know what socket it is, the OS doesn’t!
• Always check return codes!
CS 3214 Fall 2010
sendto(2), recvfrom(2)
ssize_t sendto(int s, const void *buf, size_t len, int flags, const
struct sockaddr *to, socklen_t tolen);
ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
• s, buf, len as in read/write
• flags: MSG_OOB, MSG_PEEK – mostly 0
• to/from are of type struct sockaddr_in
– These are remote/peer addresses: where did the
packet come from, where should it be sent to
• NB: fromlen is value-result!
CS 3214 Fall 2010
UDP & connect(2)
Then what does
connect() do???
• No notion of connections in UDP
– connect(2) can be used to tell OS “default destination”
for future sends
• Then can use send(2) and write(2) instead of sendto(2), or
can omit the destination address in sendto(2)
• What does “ECONNREFUSED” mean for UDP?
– Courtesy extended by other nodes which send ICMP
packet saying “no one’s listening for UDP packets at
the port number you sent it to”
– OS relayed this information to UDP application
CS 3214 Fall 2010
UDP Demultiplexing
S: 10.0.0.2:3045
D: 10.0.0.1:80
socket()
Payload
sendto(10.0.0.1:80)
socket()
bind(*, 80)
S:
S:10.0.0.2:3045
10.0.0.2:???
S: 10.0.0.1:80
10.0.0.2
recvfrom(&from)
from:10.0.0.2:3045
S: 10.0.0.3:512
D: 10.0.0.1:80
recvfrom(&from)
from:10.0.0.3:512
Payload
S: 10.0.0.1:53
recvfrom(&from)
from:10.0.0.3:512
10.0.0.1
S: 10.0.0.3:512
bind(*, 53)
S: 10.0.0.3:512
D: 10.0.0.1:53
10.0.0.3
Payload
CS 3214 Fall 2010
bind(10.0.0.3,512)
TCP: Overview
RFCs: 793, 1122, 1323,
2018, 2581
•
•
•
•
socket
door
point-to-point:
– one sender, one receiver
reliable, in-order byte stream:
– no “message boundaries”
pipelined:
– transmission proceeds even
while partially unack’ed data
send & receive buffers
application
writes data
application
reads data
TCP
send buffer
TCP
receive buffer
• full duplex data:
– bi-directional data flow in
same connection
• connection-oriented:
– handshaking (exchange
of control msgs) init’s
sender, receiver state
before data exchange
• flow controlled:
– sender will not overwhelm
socket
door
receiver
segment
CS 3214 Fall 2010
TCP Sockets
• Provide reliable byte-stream abstraction
– In-order, reliable delivery of bytes
– Bounded buffer abstraction with flow control
• Send may block if receiver application has not
drained the buffer
• Connection-oriented
– Client must connect(2)
– Server performs “passive open” using
accept(2)
CS 3214 Fall 2010
TCP Sockets: Overview
socket()
listen()
socket()
connect()
accept()
bind()
write()
read()
read()
write()
Left side:
client
Right side:
server
connection
setup
connection
shutdown
close()
close()
CS 3214 Fall 2010
connect(2)
int connect(int sockfd, const struct sockaddr *peeraddr, int addrlen)
• sockfd: returned by socket()
• peeraddr: peer’s address (type
sockaddr_in)
• this call initiates hand-shake with server
CS 3214 Fall 2010
listen(2), accept(2)
int listen(int s, int backlog)
int accept(int s, struct sockaddr *addr, int *addrlen);
• addr: accepted peer’s (aka client) address
– of type sockaddr_in
• listen() must precede accept
– No network traffic, but informs OS to start
queuing connection requests
• accept() returns new socket
– But does not assign new port – why not?
CS 3214 Fall 2010
TCP Demultiplexing
socket()
bind(*, 80)
listen(5)
10.0.0.1:80
accept()
S: 10.0.0.1:80
D: 10.0.0.2:3045
connect(10.0.0.1,80)
socket()
S: 10.0.0.2:3045
???
D: 10.0.0.1:80
S: 10.0.0.2:2047
D: 10.0.0.1:80
10.0.0.2
S: 10.0.0.1:80
D: 10.0.0.2:2047
S: 10.0.0.1:80
D: 10.0.0.3:512
10.0.0.1
bind(10.0.0.3,512)
S: 10.0.0.3:512
D: 10.0.0.1:80
10.0.0.3
connect(10.0.0.1,80)
CS 3214 Fall 2010
Utility Functions
Those shown in gray are
IPv4 specific and thus
deprecated.
in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);
int gethostname(char *name, size_t len);
int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
int getsockopt(int s, int level, int optname,
void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname,
const void *optval, socklen_t optlen);
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const char *addr, int len, int type);
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
CS 3214 Fall 2010
struct hostent
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
}
Deprecated
Use getaddrinfo(3)
instead
/* official name of host */
/* alias list */
/* host address type */
/* length of address */
/* list of addresses */
Note: IPv4 addresses, *h_addr_list points to array of long (32-bit)
Struct hostent *hent = gethostbyname(hostname);
If (hent == 0) { herror(hostname); exit(-1); }
addr = ((long*)*hent->h_addr_list)[0];
extracts first IP for host. As always, in network order!
CS 3214 Fall 2010
Common Pitfalls (3)
• What is wrong with this code?
struct sockaddr_in server1addr;
struct sockaddr_in server2addr;
/* not shown: initialize server1addr, server2addr */
printf(“using server 1 at %s and server 2 at %s\n”,
inet_ntoa(serveraddr1.sin_addr),
inet_ntoa(serveraddr2.sin_addr));
Beware of statically allocated buffers! Don’t use in new code!
Use alternatives where available: inet_ntop, getaddrinfo, etc.
CS 3214 Fall 2010
Java Binding
• Does not expose byte order
• gethostbyname()/getaddrinfo() is hidden (use
a “String” as a hostname to get default 1st IP
address)
• Does not expose bind/listen directly
• Use different types for different sockets:
– DatagramSocket, Socket, ServerSocket
• Does not expose universal file descriptor
• Hides IPv4/IPv6 behind InetAddress
superclass
CS 3214 Fall 2010
Protocol Independent
Socket Programming
• Client + server code should be unaware of which
version of IP is used
• Use getaddrinfo() to obtain information about
suitable address family and addresses
– For servers to bind to (IPv4, or IPv6, or both)
– For clients to connect to (based on DNS name or
specified address notation); based on RFC 3484
ordering
• Use getnameinfo() to transform addresses in
printable form
• See http://www.akkadia.org/drepper/userapiipv6.html for details
CS 3214 Fall 2010
Download