Sockets API - Rudra Dutta

Download Report

Transcript Sockets API - Rudra Dutta

The Sockets Library
and Concepts
Rudra Dutta
CSC 230 - Spring 2007, Section 001
API for Network Apps

Interface between TCP/IP and applications only
loosely specified
 The standards suggest the functionality (not the
details)
–
allocate resources for communication
– specify communication endpoints
– initiate a connection (client) or wait for incoming
connection (server)
– send or receive data
– terminate a connection gracefully
– handle error conditions
– etc.
Copyright Rudra Dutta, NCSU, Spring 2002
2
Unix File I/O

Program calls open() to initiate input or output
–

returns a file descriptor (small, positive integer)
Calls to read() or write() to transfer data
–
with the file descriptor as an argument

Once I/O operations are completed, the
program calls close()
 Other relevant system calls: lseek(),
ioctl()
–
(these are not used in the Sockets API)
Copyright Rudra Dutta, NCSU, Spring 2002
3
Unix File I/O Example
int fd;
char buf[256];
fd = open("a.txt", ORDWR | O_CREAT);
write(fd, buf, sizeof(buf));
close(fd);

Roughly the same for sockets, except for setup
Copyright Rudra Dutta, NCSU, Spring 2002
4
Socket API

Introduced in 1981 by BSD 4.1
–
–

implemented as system calls
originally only Unix but WinSock almost the same
Mainly, two services
–
–
datagram (UDP)
stream (TCP)
Copyright Rudra Dutta, NCSU, Spring 2002
5
The Socket Abstraction

Provides an endpoint for communication
–
–


also provides buffering
sockets are not bound to specific addresses at the time of
creation
Identified by small integer, the socket descriptor
Flexibility
–
–
–
functions that can be used with many different protocols
programmer specifies the type of service required, rather than
the protocol number
a generic address structure
Copyright Rudra Dutta, NCSU, Spring 2002
6
Endpoint Addresses

Each socket association has five components
–
–
–
–
–
protocol
local address
local port
remote address
remote port
protocol: used by socket()
 local address, port: bind()
 remote address, port: connect(), sendto()

Copyright Rudra Dutta, NCSU, Spring 2002
7
Creating A Socket
int s =

Parameters
–
–
–

socket(domain, type, protocol);
domain: PF_INET
type: SOCK_DGRAM, SOCK_STREAM,
SOCK_RAW
protocol: usually = 0 (i.e., default for type)
Example
#include <sys/types.h>
#include <sys/socket.h>
…
if ((s = socket(PF_INET, SOCK_STREAM, 0) < 0)
perror("socket");
Copyright Rudra Dutta, NCSU, Spring 2002
8
After Creating A Socket (cont'd)
Copyright Rudra Dutta, NCSU, Spring 2002
9
Generic Address Structure


Each protocol family defines its own address
representation
For each protocol family there is a corresponding
address family
–

(e.g., PF_INET  AF_INET, PF_UNIX  AF_UNIX)
Generalized address format:
–
<address family, endpoint address in family>
struct
sockaddr {
u_char
sa_len;
u_short sa_family;
char
/* total length */
/* type of address
*/
sa_data[14]; /* value of address */
};
Copyright Rudra Dutta, NCSU, Spring 2002
10
Socket Addresses, Internet Style
#include <netinet/in.h>
struct in_addr {
u_long s_addr;
/* 32-bit host address */
};
struct sockaddr_in {
u_char
sin_len;
/* total length */
short
sin_family;
/* AF_INET */
u_short
sin_port;
/* network byte order */
struct in_addr sin_addr;
char
/* network address */
sin_zero[8]; /* unused */
};
Copyright Rudra Dutta, NCSU, Spring 2002
11
Binding the Local Address
int


bind(int s, struct sockaddr *addr, int addrlen);
Used primarily by servers to specify their well-known
port
Optional for clients
–

normally, system chooses a “random” local port
Use INADDR_ANY to allow the socket to receive
datagrams sent to any of the machine's IP addresses
Copyright Rudra Dutta, NCSU, Spring 2002
12
Binding the Local Address (cont'd)
…
sin.sin_family
sin.sin_port
chooses */
sin.sin_addr.s_addr
interface */
if (bind(s, (struct
/* error function
Copyright Rudra Dutta, NCSU, Spring 2002
= AF_INET;
= htons(6000); /* if 0:system
= INADDR_ANY;
/* allow any
sockaddr *)&sin, sizeof(sin)) < 0)
here */
13
After Binding the Local Address
Copyright Rudra Dutta, NCSU, Spring 2002
14
Establish a Connection Queue
int
listen(int s, int backlog);

Only used for stream sockets
 Used by connection-oriented servers to place a
socket in passive mode
–
–

makes it ready to accept incoming connections
the remote port # / IP address of the socket = 0 (any
port, any IP address)
Allows backlog pending connections to be
waiting for accept()
Copyright Rudra Dutta, NCSU, Spring 2002
15
Accepting Connection Requests
newsock =

Executed by connection-oriented server, after
listen()
–

accept(int s, struct sockaddr *clientaddr,
int *clientaddrlen);
blocks until a connection request from a client arrives
Returns a new, unique socket (newsock) for data
exchange with the client
–
–
this new socket is for the connection with port # / IP
address of the client as the remote port and IP address
this new socket must be closed when the client and
server are through communicating
Copyright Rudra Dutta, NCSU, Spring 2002
16
Accepting Connection Requests

The original socket s (with 0 as remote address)
remains open
–

when a TCP segment arrives for this host/port, and no
existing socket has a remote IP address / port # = to the
source IP address/port of the segment, the segment will
be sent to the original socket s
Must call accept() again to obtain the next
connection request
Copyright Rudra Dutta, NCSU, Spring 2002
17
Accepting Connections (cont'd)
Copyright Rudra Dutta, NCSU, Spring 2002
18
Connecting To A Server
int

Binds a permanent destination to a socket
–

uses 3-way handshake to establish connection (active open)
As a side effect, it chooses a local endpoint (IP address
and port number) if the socket does not have one
–

connect(int s, struct sockaddr *servername,
int servernamelen);
Cients normally let the system choose their (ephemeral) port #
May fail
–
–
host not listening to port
timeout
Copyright Rudra Dutta, NCSU, Spring 2002
19
Client-Server
Interaction:
TCP
Copyright Rudra Dutta, NCSU, Spring 2002
20
Sending and Receiving Data

Types
–
–
–

Options: flags which modify action of a call
–

read(), write()
recv(), send()
recvfrom(), sendto()
read() and write() may not specify options
Notes
–
–
block size read may not = block size written
read from stream may read fewer bytes than
requested
Copyright Rudra Dutta, NCSU, Spring 2002
21
Sending Data

int
write(int s, char* buf, int buflen);
int
send(int s, char* buf, int buflen, int flags);
Flags control transmission
–

E.g., specify urgent data
Write might not be able to write all buflen bytes
(on a nonblocking socket)
Copyright Rudra Dutta, NCSU, Spring 2002
22
Receiving Data

int
read(int s, char* buf, int buflen);
int
recv(int s, char* buf, int buflen, int flags);
Flags control reception, e.g.,
–
–

Reminder!
–
–

out-of-band data
message look-ahead
block size read may not = block size written
read from stream may read fewer bytes than requested
If the other end has closed the connection, and there is
no buffered data, reading from a TCP socket returns 0 to
indicate EOF
Copyright Rudra Dutta, NCSU, Spring 2002
23
Closing A Connection
int

Actions
–
–

close(int s);
decrements reference count for socket
terminates communication gracefully and removes
socket when reference count = 0
Problem
–
server does not know if client has additional requests
– client does not know if server has additional data to send
Copyright Rudra Dutta, NCSU, Spring 2002
24
Partially Closing A Connection
int

shutdown(int s, int direction);
Direction
–
0 to close the input (reading) end
– 1 to close the output (writing) end
– 2 for both

Used by client to specify it has no more data to
send, without deallocating connection
 Server receives an EOF signal on read() or
recv(), can then close connection after
sending its last response
Copyright Rudra Dutta, NCSU, Spring 2002
25
Datagram Communication
int
sendto(int s, char *buf, int buflen, int flags,
struct sockaddr *to, int tolen);
First 4 arguments same as in send()
 Sends buflen bytes in buffer buf to location
to, with options flags (usually 0)
 The return value of sendto() indicates how much
data was accepted by the O.S. for sending as a
datagram

–
–
not how much data made it to the destination
there is no error condition that indicates the destination
did not get the data!
Copyright Rudra Dutta, NCSU, Spring 2002
26
Datagram Communication (cont’d)
int


recvfrom(int s, char *buf, int buflen, int flags,
struct socaddr *from, int fromlen);
First 4 arguments same as in recv()
Receives up to len bytes into buffer buf
–
–


returns number of bytes received, 0 on EOF
if buf is not large enough, any extra data is lost forever
recvfrom blocks until datagram available, by default
Sets from to source address of data
–
sending replies is easy
Copyright Rudra Dutta, NCSU, Spring 2002
27
Connected vs. Unconnected UDP
Sockets

UDP sockets can be connected or
unconnected
–
–
in connected mode, client uses connect() to
specify a remote endpoint
convenient to interact with a specific server
repeatedly
connect(): only records the remote address,
does not initiate any packet exchange
 write(): sends a single message to the
server
 read(): returns one complete message

Copyright Rudra Dutta, NCSU, Spring 2002
28
Closing UDP Sockets

close()
–
–

releases the resources associated with a socket
does not inform the remote endpoint that the socket
is closed
shutdown()
–
–
can be used to mark socket as unwilling to transfer
data in the direction specified
does not send any message to the other side
Copyright Rudra Dutta, NCSU, Spring 2002
29
Client-Server Interaction: UDP
• Contrast with TCP
Copyright Rudra Dutta, NCSU, Spring 2002
30
Byte Ordering Representation
Copyright Rudra Dutta, NCSU, Spring 2002
31
Byte-Order Transformations
Copyright Rudra Dutta, NCSU, Spring 2002
32

Byte-Order Transformations
(cont’d)
Byte ordering is a function of machine architecture
–
–
–

Intel: little-endian
Sparc, PowerPC: big-endian
Network order: big-endian
Functions
–
u_long m =

–
–
htonl(u_long m)
host-to-network byte order, 32 bit
ntohs(),


network-to-host byte order, 32 bit
u_long m =

ntohl(u_long m)
htons()
short (16 bit)
Be safe; it never hurts to use, and it improves
portability
Copyright Rudra Dutta, NCSU, Spring 2002
33
Address Conversions

Internally, IP addresses are represented as 32-bit
integers
int addr =

inet_addr(char *str)
addr: network byte order, str: dotted decimal form
char *str =
Copyright Rudra Dutta, NCSU, Spring 2002
inet_ntoa(struct in_addr in)
34
Obtaining Information About
Hosts, etc.
struct hostent *hptr;
address in
/* includes host
binary */
hptr = gethostbyname(char *name);
Ex.: gethostbyname(“www.csc.ncsu.edu”);
struct hostent *hptr;
hptr = gethostbyaddr(char *addr, int
addrlen,
int addrtype);
Ex.: gethostbyaddr(&addr, 4, AF_INET);
Copyright Rudra Dutta, NCSU, Spring 2002
35
Obtaining Information
int inet_addr(char *dotdecimal);
Ex.: sin_addr = inet_addr(“152.14.51.129”);
struct servent *sptr; /* includes port and
protocol */
sptr = getservbyname(char *name, char
*proto);
Ex.: getservbyname(“smtp”, “tcp”);
struct protoent *pptr; /* includes protocol
number */
pptr = getprotobyname(char *name);
Ex.: getprotobyname(“tcp”);
Copyright Rudra Dutta, NCSU, Spring 2002
36
Example of Connection
Establishment
// host
- name of host to which connection is desired
// service
- service associated with the desired port
// transport - name of transport protocol to use ("tcp“, "udp")
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
/* Map service name to port number */
if ( pse = getservbyname(service, transport) )
sin.sin_port = pse->s_port;
else if ((sin.sin_port =
htons((unsigned short)atoi(service))) == 0)
errexit("can't get \"%s\" service entry\n", service);
Copyright Rudra Dutta, NCSU, Spring 2002
37
Example (cont’d)
/* Map host name to IP address, allowing for dotted decimal */
if ( phe = gethostbyname(host) )
memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
errexit("can't get \"%s\" host entry\n", host);
/* Map transport protocol name to protocol number */
if ( (ppe = getprotobyname(transport)) == 0)
errexit("can't get \"%s\" protocol entry\n", transport);
Copyright Rudra Dutta, NCSU, Spring 2002
38
Example (cont’d)
/* Use protocol to choose a socket type */
if (strcmp(transport, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;
/* Allocate a socket */
s = socket(PF_INET, type, ppe->p_proto);
if (s < 0)
errexit("can't create socket: %s\n", strerror(errno));
Copyright Rudra Dutta, NCSU, Spring 2002
39
Example (cont’d)
/* Connect the socket */
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
errexit("can't connect to %s.%s: %s\n", host, service,
strerror(errno));
return s;
Copyright Rudra Dutta, NCSU, Spring 2002
40