Transcript socket
TCP/IP Sockets
ECS 152B
ECS152B
Xin Liu
What is a socket?
• API: network programming interface
• Socket: abstraction through which an application
may send/receive data.
• Allows an application to “plug-in” a network and
communicates with other apps. in the same
network.
• Sockets: different underlying protocol families.
Application
Sockets
Protocol A Protocol B Protocol C
ECS152B
Xin Liu
TCP/IP
• TCP/IP does not include an API definition.
• There are a variety of APIs for use with
TCP/IP:
–
–
–
–
ECS152B
Sockets (Berkeley sockets)
TLI (Transport layer interface by AT&T)
Winsock
MacTCP
Xin Liu
Functions needed
• Specify local and remote communication
endpoints
• Initiate a connection
• Wait for incoming connection
• Send and receive data
• Terminate a connection gracefully
• Error handling
ECS152B
Xin Liu
Sockets, protocols, ports
Applications
sockets
Applications
sockets
sockets
binding
ports
TCP/UDP
IP
ECS152B
Xin Liu
Creating a Socket
int socket(int family,int type,int proto);
• family specifies the protocol family (PF_INET for
TCP/IP).
• type specifies the type of service (SOCK_STREAM,
SOCK_DGRAM).
– SOCK_STREAM: reliable byte-stream
– SOCK_DGRAM: best-effort datragram
• protocol specifies the specific protocol
– IPPROTO_TCP, IPPROTO_UDP
– 0 means the default
ECS152B
Xin Liu
socket()
• The socket() system call returns a
socket descriptor (nonnegative) or -1 on
error.
• socket() allocates resources needed for a
communication endpoint - but it does not
deal with endpoint addressing.
ECS152B
Xin Liu
Unix Descriptor Table
Descriptor Table
Data structure for file 0
0
1
2
Data structure for file 1
3
4
ECS152B
Data structure for file 2
Xin Liu
Socket Descriptor Data Structure
Descriptor Table
0
1
2
3
Family: PF_INET
Service: SOCK_STREAM
Local IP: 111.22.3.4
Remote IP: 123.45.6.78
Local Port: 2249
Remote Port: 3726
4
ECS152B
Xin Liu
Necessary Background Information:
POSIX data types
int8_t
uint8_t
int16_t
uint16_t
int32_t
uint32_t
ECS152B
signed 8bit int
unsigned 8 bit int
signed 16 bit int
unsigned 16 bit int
signed 32 bit int
unsigned 32 bit int
Xin Liu
More POSIX data types
sa_family_t
socklen_t
in_addr_t
in_port_t
ECS152B
address family
length of struct
IPv4 address
IP port number
Xin Liu
Generic socket addresses
struct sockaddr {
unsigned short
sa_family;
char
sa_data[14];
};
• sa_family specifies the address type
– AF_INET (Internet protocol address family)
• sa_data specifies the address value.
ECS152B
Xin Liu
struct sockaddr_in (IPv4)
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char
sin_zero[8];
};
struct in_addr {
unsigned long
};
ECS152B
s_addr;
Xin Liu
Address
• sockaddr_in is another view of the
data in sockaddr structure.
• Fill, cast, and pass to the socket
functions
• Socket functions look at the
sa_family
• PF_INET and AF_INET:
– allow maximum flexibility, e.g., the
same protocol family can use
different address families.
ECS152B
Xin Liu
sockaddr
sockaddr_in
sa_family
AF_INET
sin_port
sin_addr
sa_data
sin_zero
ECS152B
Xin Liu
Network Byte Order
• All values stored in a sockaddr_in
must be in network byte order.
– sin_port
– sin_addr
ECS152B
a TCP/IP port number.
an IP address.
Xin Liu
Byte Ordering
• Big-Endian machine: the most significant
byte has the lowest address
– Motorola 68000 and Sparc
• Little-Endian machine: the least significant
byte has the lowest address
– Intel x86 and DEC Alpha architectures
• Network byte order: Big-Endian
ECS152B
Xin Liu
Network Byte Order Functions
‘h’ : host byte order
‘n’ : network byte order
‘s’ : short (16bit)
‘l’ : long (32bit)
uint16_t htons(uint16_t);
uint16_t ntohs(uint_16_t);
uint32_t htonl(uint32_t);
uint32_t ntohl(uint32_t);
ECS152B
Xin Liu
Byte ordering
• Whenever sending a multibyte, binary value
from one machine to another machine
• Passing values to an API function in
sockaddr structure
myaddr.sin_port = htons( portnum );
myaddr.sin_addr = htonl( ipaddress);
• Receiver needs to convert before
using the values
ECS152B
Xin Liu
Allocation of Port Numbers
1
BSD
reserved
ports
1
5000 5001
1023 1024
65535
BSD
servers
(nonprivilidged)
BSD
ephemeral
(short lived)
ports
1023 1024
IANA
well-known
ports
49151
49152
IANA
dynamic or
private
IANA
registered
ports
IANA: Internet Assigned Numbers Authority
ECS152B
Xin Liu
65535
Assigning an address to a socket
• The bind() system call is used to assign an
address to an existing socket.
int bind( int sockfd,
const struct sockaddr *myaddr,
int addrlen);
• bind returns 0 if successful or -1 on error.
ECS152B
Xin Liu
bind()
• calling bind() assigns the address
specified by the sockaddr structure to the
socket descriptor.
• You can give bind() a sockaddr_in
structure:
bind( mysock,
(struct sockaddr*) &myaddr,
sizeof(myaddr) );
ECS152B
Xin Liu
bind() Example
int mysock,err;
struct sockaddr_in myaddr;
memset(&myaddr, 0, sizeof(myaddr));
mysock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( portnum );
myaddr.sin_addr = htonl( ipaddress);
err=bind(mysock, (sockaddr *) &myaddr,
sizeof(myaddr));
if (err<0)
HandleError;
ECS152B
Xin Liu
Uses for bind()
• There are a number of uses for bind():
– Server would like to bind to a well known
address (port number).
– Client can bind to a specific port.
– Client can ask the O.S. to assign any available
port number.
ECS152B
Xin Liu
Framing
• TCP: stream service, does not conserve
boundary
• Framing: formatting the information s.t. the
receiver can parse message
– The beginning and end of the message,
boundaries between fields within the message
– Fixed message size
– Using delimiter
ECS152B
Xin Liu
TCP Clients
•
•
•
•
ECS152B
Create a socket, socket()
Establish connection to the server, connect()
Communicate, send() and recv()
Close connection, close()
Xin Liu
connect()
int connect( int sockfd,
const struct sockaddr *foreignserver,
socklen_t addrlen);
sockfd is an already created TCP socket.
foreignserver contains the address of the server
(IP Address and TCP port number)
connect() returns 0 if OK, -1 on error
ECS152B
Xin Liu
Client Code
• TCP clients can call connect() which:
– takes care of establishing an endpoint address
for the client socket.
• don’t need to call bind first, the O.S. will take care
of assigning the local endpoint address (TCP port
number, IP address).
– Attempts to establish a connection to the
specified server.
• 3-way handshake
ECS152B
Xin Liu
Send/receive in a TCP socket
int send(int sd, const void *buf,
unsigned int messagelen, int flags);
int recv(int sd, void *buf, unsigned int
bufferlen, int flags);
sd: socket descriptor
flags: change default behavior, 0 default
Return: -1 for error
ECS152B
Xin Liu
TCP Server
• Creating a passive mode (server) socket.
• Establishing an application-level
connection.
• send/receive data.
• Terminating a connection.
ECS152B
Xin Liu
listen()
int listen( int sockfd, int backlog);
sockfd is the TCP socket (already bound to an
address)
backlog is the number of incoming connections
the kernel should be able to keep track of (queue
for us).
listen() returns -1 on error (otherwise 0).
ECS152B
Xin Liu
accept()
int accept( int sockfd,
struct sockaddr* cliaddr,
socklen_t *addrlen);
sockfd is the passive mode TCP socket.
cliaddr is a pointer to allocated space.
addrlen is a value-result argument
– must be set to the size of cliaddr
– on return, will be set to be the number of used
bytes in cliaddr.
ECS152B
Xin Liu
accept() return value
accept() returns a new socket descriptor
(small positive integer) or -1 on error.
After accept returns a new socket descriptor, I/O
can be done using the send()& recv() system
calls.
ECS152B
Xin Liu
Terminating a TCP connection
• Either end of the connection can call the
close() system call.
• If the other end has closed the connection,
and there is no buffered data, reading from a
TCP socket returns 0 to indicate EOF.
ECS152B
Xin Liu
Metaphor for Good Relationships
To succeed in relationships:
– you need to establish your own identity.
– you need to be open & accepting.
– you need to establish contacts.
– you need to take things as they come, not as
you expect them.
ECS152B
Xin Liu
A simple client example
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr));
echoServAddr.sin_family = AF_INET;
echoServAddr.sin_addr.s_addr = inet_addr(servIP);
echoServAddr.sin_port
= htons(echoServPort);
ECS152B
Xin Liu
/* Establish the connection to the echo server */
if (connect(sock, (struct sockaddr *) &echoServAddr,
sizeof(echoServAddr)) < 0)
DieWithError("connect() failed");
echoStringLen = strlen(echoString);
/* Determine input length
*/
/* Send the string to the server */
if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
DieWithError("send() sent a different number of bytes than
expected");
ECS152B
Xin Liu
A
simple
TCP
Server
/* Create socket for incoming connections */
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* Construct local address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET;
/* Internet address family */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming
interface */
echoServAddr.sin_port = htons(echoServPort); /* Local port */
/* Bind to the local address */
if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) <
0)
DieWithError("bind() failed");
/* Mark the socket so it will listen for incoming connections */
if (listen(servSock, MAXPENDING) < 0)
DieWithError("listen() failed");
ECS152B
Xin Liu
for (;;) /* Run forever */
{
/* Set the size of the in-out parameter */
clntLen = sizeof(echoClntAddr);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr,
&clntLen)) < 0)
DieWithError("accept() failed");
/* clntSock is connected to a client! */
printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
HandleTCPClient(clntSock);
}
/* NOT REACHED */
}
ECS152B
Xin Liu
Under the hook
•
•
•
•
•
ECS152B
Data structure
Buffering and TCP
Deadlock
Performance
TCP socket life cycle
Xin Liu
Data structure of a TCP socket
Socket
descriptor
recved
queue
sent
queue
protocol state (closed)
Local IP: 111.22.3.4
Remote IP: 123.45.6.78
Local Port: 2249
Remote Port: 3726
ECS152B
Xin Liu
UDP
Local IP: 111.22.3.4
Remote IP: 123.45.6.78
Local Port: 2249
Remote Port: 3726
ECS152B
Xin Liu
Buffering and TCP
Cannot assume correspondence between send()s
and recv()s
Ex:
connect(s,…);
send(s, buffer0,1000,0);…
send(s, buffer1,2000,0);…
send(s, buffer2,5000,0);…
close(s)
ECS152B
Xin Liu
Queues
• SendQ
• RecvQ
• Delivered
ECS152B
Xin Liu
Deadlock
• N>SendQ+RecvQ
• Notes: design the protocol carefully to
avoid simultaneous send() in both
directions.
ECS152B
Xin Liu
Performance
• Effective size of send() is limited by SendQ
size.
• Can change using SO_RCVBUF &
SO_SNDBUF socket options.
ECS152B
Xin Liu
TCP Socket life cycle
• Client:
– Connecting
• Server:
– Binding
– Listen
– Accept
ECS152B
Xin Liu