IPv4 Socket AddressStructure
■ Commonly called an "Internet socket address structure,"
■ sockaddr_in
■ #include <netinet/in.h>
4.
struct in_addr {
in_addr_ts_addr; /* 32-bit IPv4 address */
/* network byte ordered */
};
struct sockaddr_in {
uint8_t sin_len; /* length of structure (16) */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 16-bit TCP or UDP port
number */
/* network byte ordered */
struct in_addr sin_addr; /* 32-bit IPv4 address */
/* network byte ordered */
char sin_zero[8]; /* unused */
};
The POSIX specification requires
only three members in the
structure: sin_family, sin_addr,
and sin_port.
Both the IPv4 address and the TCP
or UDP port number are always
stored in the structure in network
byte order.
The 32-bit IPv4 address can be
accessed in two different ways.
For example, if serv is defined as an
Internet socket address structure, then
serv.sin_addr references the 32-bit
IPv4 address as an in_addr structure,
while serv.sin_addr.s_addr references
the same 32-bit IPv4 address as an
in_addr_t
5.
int8_t
uint8_t
int16_t
unit16_t
int32_t
unit32_t
Signed 8-bit integer
Unsigned8-bit integer
Signed 16-bit integer
Unsigned 16-bit integer
Signed 32-bit integer
Unsigned 32-bit integer
<sys/types.h>
<sys/types.h>
<sys/types.h>
<sys/types.h>
<sys/types.h>
<sys/types.h>
sa_family_t
socklen_t
Address family of socket address structure
Length of socket address structure, normally uint32_t
<sys/socket.h>
<sys/socket.h>
in_addr_t
in_port_t
IPv4 address, normally uint32_t
TCP or UDP port , normally uint16_t
<netinet/in.h>
<netinet/in.h>
6.
IPv6 Socket AddressStructure
■ Commonly called an "Internet socket address structure Version 6,"
■ sockaddr_in6
■ #include <netinet/in.h>
7.
The sin6_flowinfo
member isdivided into
two fields:
• The low-order 20 bits
are the flow label
• The high-order 12 bits
are reserved
The sin6_scope_id
identifies the scope zone
in which a scoped
address is meaningful,
most commonly an
interface index for a link-
local address
struct in6_addr {
uint8_t s6_addr[16]; /* 128-bit IPv6 address */
/* network byte ordered */
};
#define SIN6_LEN /* required for compile-time tests */
struct sockaddr_in6 {
uint8_t sin6_len; /* length of this struct (28) */
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* transport layer port# */
/* network byte ordered */
uint32_t sin6_flowinfo; /* flow information, undefined */
struct in6_addr sin6_addr; /* IPv6 address */
/* network byte ordered */
uint32_t sin6_scope_id; /* set of interfaces for a scope */
};
8.
Value-Result
Arguments
■ When asocket address structure is
passed to any socket function, it is
always passed by reference (a pointer to
the structure is passed).
■ The length of the structure is also
passed as an argument.
■ The way in which the length is passed
depends on which direction the
structure is being passed:
1. From the process to the kernel
2. From the kernel to the process
9.
From process to
kernel
■bind, connect, and sendto
functions pass a socket
address structure from the
process to the kernel.
■ Arguments to these
functions:
– The pointer to the
socket address
structure
– The integer size of the
structure
10.
From kernel to
process
■accept, recvfrom, getsockname,
and getpeername functions pass a
socket address structure from the
kernel to the process.
■ Arguments to these functions:
– The pointer to the socket
address structure
– The pointer to an integer
containing the size of the
structure.
11.
Byte Ordering
Functions
■ Fora 16-bit integer that is
made up of 2 bytes, there are
two ways to store the two
bytes in memory:
• Little-endian order: low-
order byte is at the starting
address.
• Big-endian order: high-order
byte is at the starting
address.
12.
Byte Ordering Functions
#include<netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
/* Both return: value in network byte order */
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);
/* Both return: value in host byte order */
13.
Byte Manipulation Functions
■The functions that operate on multibyte fields, without interpreting the data, and
without assuming that the data is a null-terminated C string. These types of
functions deal with socket address structures to manipulate fields such as IP
addresses, which can contain bytes of 0, but are not C character strings.
– The functions whose names begin with b (for byte) (from 4.2BSD)
– The functions whose names begin with mem (for memory) (from ANSI C)
14.
The functions whosenames begin with b (for byte)
(from 4.2BSD)
#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
15.
The functions whosenames begin with
mem (for memory) (from ANSI C)
#include <strings.h>
void*memset(void*dest,intc,size_tlen);
void*memcpy(void*dest,constvoid*src,size_tnbytes);
intmemcmp(constvoid*ptr1,constvoid*ptr2,size_tnbytes);
16.
inet_aton
■ These functionsconvert Internet addresses between ASCII strings (what humans
prefer to use) and network byte ordered binary values (values that are stored in
socket address structures)
■ #include <arpa/inet.h>
■ int inet_aton(const char *strptr, struct in_addr *addrptr);
– /* Returns: 1 if string was valid, 0 on error */
■ converts the C character string pointed to by strptr into its 32-bit binary network byte
ordered value, which is stored through the pointer addrptr
17.
inet_addr
■ #include <arpa/inet.h>
■in_addr_t inet_addr(const char *strptr);
■ /* Returns: 32-bit binary network byte ordered IPv4 address; INADDR_NONE if error */
■ does the same conversion, returning the 32-bit binary network byte ordered value as the
return value. It is deprecated and any new code should use inet_aton instead
18.
inet_ntoa
■ #include <arpa/inet.h>
■char *inet_ntoa(struct in_addr inaddr);
■ /* Returns: pointer to dotted-decimal string */
■ converts a 32-bit binary network byte ordered IPv4 address into its corresponding
dotted-decimal string
19.
inet_pton and inet_ntopFunctions
■ These two functions are new with IPv6 and work with both IPv4 and IPv6 addresses. We use
these two functions throughout the text. The letters "p" and "n" stand
for presentation and numeric.
■ #include <arpa/inet.h>
■ int inet_pton(int family, const char *strptr, void *addrptr);
■ /* Returns: 1 if OK, 0 if input not a valid presentation format, -1 on error */
■ const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
■ /* Returns: pointer to result if OK, NULL on error */
socket Function
■ #include<sys/socket.h>
■ int socket (int family, int type, int
protocol);
■ /* Returns: non-negative
descriptor if OK, -1 on error */
Arguments
family Description
AF_INET IPv4 protocols
AF_INET6 IPv6 protocols
AF_LOCAL Unix domain protocols (
Chapter 15)
AF_ROUTE Routing sockets (Chapter 18
)
AF_KEY Key socket (Chapter 19)
family specifies the protocol family and is one of the constants
in the table below. This argument is often referred to
as domain instead of family.
25.
type Description
SOCK_STREAM streamsocket
SOCK_DGRAM datagram socket
SOCK_SEQPACKET sequenced packet socket
SOCK_RAW raw socket
The socket type is one of the constants shown in table
below:
The protocol argument to the socket function should be set to the specific protocol type found
in the table below, or 0 to select the system's default for the given combination
of family and type.
protocol Description
IPPROTO_TCP TCP transport protocol
IPPROTO_UDP UDP transport protocol
IPPROTO_SCTP SCTP transport protocol
26.
connect Function
■ heconnect function is used by a TCP client to establish a connection with a TCP server.
■ #include <sys/socket.h>
■ int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
■ /* Returns: 0 if OK, -1 on error */
■ sockfd is a socket descriptor returned by the socket function.
■ The servaddr and addrlen arguments are a pointer to a socket address structure (which
contains the IP address and port number of the server) and its size.
27.
bind Function
■ Thebind function assigns a local protocol address to a socket. The protocol address
is the combination of either a 32-bit IPv4 address or a 128-bit IPv6 address, along
with a 16-bit TCP or UDP port number.
■ #include <sys/socket.h>
■ int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
■ /* Returns: 0 if OK,-1 on error */
■ The second argument myaddr is a pointer to a protocol-specific addres
■ The third argument addrlen is the size of this address structure.
28.
listen Function
■ Listen(intfd, int backlog)
■ The listen function is called only by a TCP server and it performs two actions:
– The listen function converts an unconnected socket into a passive socket,
indicating that the kernel should accept incoming connection requests directed to
this socket.
■ When a socket is created by the socket function (and before calling listen), it is
assumed to be an active socket, that is, a client socket that will issue a connect.
– The second argument backlog to this function specifies the maximum number of
connections the kernel should queue for this socket.
■ This function is normally called after both the socket and bind functions and must be
called before calling the accept function.
29.
Connection
queues *
To understand
thebacklog argument, we must
realize that for a given listening
socket, the kernel maintains two
queues:
1.An incomplete connection
queue, which contains an entry
for each SYN that has arrived from
a client for which the server is
awaiting completion of the TCP
three-way handshake
2.A completed connection
queue, which contains an entry
for each client with whom the TCP
three-way handshake has
completed.
30.
accept Function
■ acceptis called by a TCP server to return the next completed connection from the
front of the completed connection queue. If the completed connection queue is
empty, the process is put to sleep.
■ #include <sys/socket.h>
■ int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
■ /* Returns: non-negative descriptor if OK, -1 on error */
■ The cliaddr and addrlen arguments are used to return the protocol address of the
connected peer process (the client). addrlen is a value-result argument
31.
fork and exec
Functions
■when a client request can
take longer to service, we do
not want to tie up a single
server with one client; we
want to handle multiple
clients at the same time.
■ The simplest way to write a
concurrent server under
Unix is to fork a child
process to handle each
client.
#include <unistd.h>
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, -1 on error
32.
■ There aretwo typical uses of fork:
1. A process makes a copy of itself so that one copy can handle one operation while the other copy
does another task. This is typical for network servers. We will see many examples of this later in
the text.
2. A process wants to execute another program. Since the only way to create a new process is by
calling fork, the process first calls fork to make a copy of itself, and then one of the copies
(typically the child process) calls exec (described next) to replace itself with the new program.
This is typical for programs such as shells.
33.
#INCLUDE <UNISTD.H>
Int execl(const char *pathname, const char *arg0, ... /* (char *) 0 */ );
Int execv (const char *pathname, char *constargv[]);
Int execle (const char *pathname, const char *arg0, ...
/* (char *) 0, char *constenvp[] */ );
Int execve (const char *pathname, char *constargv[], char *constenvp[]);
Int execlp (const char *filename, const char *arg0, ... /* (char *) 0 */ );
Int execvp (const char *filename, char *constargv[]);
All six return: -1 on error, no return on success
34.
Concurrent
Servers
pid_t pid;
int listenfd,connfd;
listenfd = Socket( ... );
/* fill in sockaddr_in{} with server's well-known port */
Bind(listenfd, ... );
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept (listenfd, ... ); /* probably blocks */
if( (pid = Fork()) == 0) {
Close(listenfd); /* child closes listening socket */
doit(connfd); /* process the request */
Close(connfd); /* done with this client */
exit(0); /* child terminates */
}
Close(connfd); /* parent closes connected socket */
}
close Function
■ Thenormal Unix close function is also used to close a socket and terminate a TCP
connection.
■ #include <unistd.h>
■ int close (int sockfd);
■ /* Returns: 0 if OK, -1 on error */
40.
Client Side (dependson connection
type):
Server Side (depends on connection
type):
Socket Socket
Connect Bind
Write (may be repeated) Listen
Read (may be repeated) Accept
Close Read (may be repeated)
Write (may be repeated)
Close (go back to Accept)
41.
getsockname and getpeername
Functions
■#include <sys/socket.h>
■ Int getsockname(int sockfd, structsockaddr *localaddr, socklen_t *addrlen);
■ Int getpeername(int sockfd, structsockaddr *peeraddr, socklen_t *addrlen);
■ Both return: 0 if OK, -1 on error