Title: TCP/IP Sockets
1TCP/IP Sockets
2What 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.
3TCP/IP
- TCP/IP does not include an API definition.
- There are a variety of APIs for use with TCP/IP
- Sockets (Berkeley sockets)
- TLI (Transport layer interface by ATT)
- Winsock
- MacTCP
4Functions needed
- Specify local and remote communication endpoints
- Initiate a connection
- Wait for incoming connection
- Send and receive data
- Terminate a connection gracefully
- Error handling
5Sockets, protocols, ports
6Creating 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
7socket()
- 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.
8Unix Descriptor Table
Descriptor Table
Data structure for file 0
0
1
Data structure for file 1
2
3
Data structure for file 2
4
9Socket Descriptor Data Structure
Descriptor Table
Family PF_INET Service SOCK_STREAM Local IP
111.22.3.4 Remote IP 123.45.6.78 Local Port
2249 Remote Port 3726
0
1
2
3
4
10Necessary Background Information POSIX data
types
- int8_t signed 8bit int
- uint8_t unsigned 8 bit int
- int16_t signed 16 bit int
- uint16_t unsigned 16 bit int
- int32_t signed 32 bit int
- uint32_t unsigned 32 bit int
11More POSIX data types
- sa_family_t address family
- socklen_t length of struct
- in_addr_t IPv4 address
- in_port_t IP port number
12Generic socket addresses
- struct sockaddr
- unsigned short sa_family
- char sa_data14
-
- sa_family specifies the address type
- AF_INET (Internet protocol address family)
- sa_data specifies the address value.
13struct sockaddr_in (IPv4)
- struct sockaddr_in
- unsigned short sin_family
- unsigned short sin_port
- struct in_addr sin_addr
- char sin_zero8
-
- struct in_addr
- unsigned long s_addr
-
14Address
- 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.
15sockaddr_in
sockaddr
sa_family
sa_data
16Network Byte Order
- All values stored in a sockaddr_in must be in
network byte order. - sin_port a TCP/IP port number.
- sin_addr an IP address.
Common Mistake Ignoring Network Byte Order
17Byte 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
18Network 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)
19Byte 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
20Allocation of Port Numbers
5001 65535
1 1023
1024 5000
BSD servers (nonprivilidged)
BSD reserved ports
BSD ephemeral (short lived) ports
49152 65535
1 1023
1024
49151
IANA dynamic or private
IANA registered ports
IANA well-known ports
IANA Internet Assigned Numbers Authority
21Assigning 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.
const!
22bind()
- 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) )
23bind() Example
- int mysock,err
- struct sockaddr_in myaddr
- memset(myaddr, 0, sizeof(myaddr))
- mysock socket(PF_INET,SOCK_STREAM,IPPROTO_T
CP) - myaddr.sin_family AF_INET
- myaddr.sin_port htons( portnum )
- myaddr.sin_addr htonl( ipaddress)
- errbind(mysock, (sockaddr ) myaddr,
sizeof(myaddr)) - if (errlt0)
- HandleError
24Uses 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.
25Framing
- 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
26TCP Clients
- Create a socket, socket()
- Establish connection to the server, connect()
- Communicate, send() and recv()
- Close connection, close()
27connect()
- 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
28Client Code
- TCP clients can call connect() which
- takes care of establishing an endpoint address
for the client socket. - dont 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
29Send/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
30TCP Server
- Creating a passive mode (server) socket.
- Establishing an application-level connection.
- send/receive data.
- Terminating a connection.
31listen()
- 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).
32accept()
- 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.
33accept() 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.
34Terminating 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.
35Metaphor 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.
bind()
accept()
connect()
read might return 1 byte
36A simple client example
/ Create a reliable, stream socket using TCP
/ if ((sock socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 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)
37 / Establish the connection to the echo server
/ if (connect(sock, (struct sockaddr )
echoServAddr, sizeof(echoServAddr)) lt 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")
38A simple TCP Server
/ Create socket for incoming connections /
if ((servSock socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 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))
lt 0) DieWithError("bind() failed")
/ Mark the socket so it will listen for incoming
connections / if (listen(servSock,
MAXPENDING) lt 0) DieWithError("listen()
failed")
39 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)) lt 0) DieWithError("accept()
failed") / clntSock is connected to a
client! / printf("Handling client
s\n", inet_ntoa(echoClntAddr.sin_addr))
HandleTCPClient(clntSock) / NOT
REACHED /
40Under the hook
- Data structure
- Buffering and TCP
- Deadlock
- Performance
- TCP socket life cycle
41Data 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
42UDP
- Local IP 111.22.3.4
- Remote IP 123.45.6.78
- Local Port 2249
- Remote Port 3726
43Buffering 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)
44Queues
45Deadlock
- NgtSendQRecvQ
- Notes design the protocol carefully to avoid
simultaneous send() in both directions.
46Performance
- Effective size of send() is limited by SendQ
size. - Can change using SO_RCVBUF SO_SNDBUF socket
options.
47TCP Socket life cycle
- Client
- Connecting
- Server
- Binding
- Listen
- Accept