Title: By: Dr' Vasos Vassiliou and Pavlos Antoniou
1CS420 Tutorials on High Speed Multimedia and
Multiservice Networks TCP/IP Socket Programming
in C
- By Dr. Vasos Vassiliou and Pavlos Antoniou
- Spring 2008
2Overview
- Introduction
- TCP/IP Basic
- UNIX/C Sockets
- UDP Sockets
- TCP Sockets
- Utility Functions
- Other Socket API
- Summary
3Internet Protocol (IP)
- Datagram (packet) protocol
- Best-effort service
- Loss
- Reordering
- Duplication
- Delay
- Host-to-host delivery (not application-to-applica
tion)
4IP Address
- 32-bit identifier
- Identifies a host interface (not a host)
5Transport Protocols
- Best-effort is not sufficient !!!
- Add services on top of IP
- User Datagram Protocol (UDP)
- Data checksum
- Best-effort
- Transmission Control Protocol (TCP)
- Data checksum
- Reliable byte-stream delivery
- Flow and congestion control
6Ports
- Identifying the ultimate destination
- IP addresses identify hosts
- Host has many applications
- Ports (16-bit identifier)
Application WWW E-mail Telnet
Port 80 25 23
194.42.16.25
7TCP/IP Byte Transport
- TCP/IP protocols transports bytes
- Application protocol provides semantics
Application
Application
byte stream
byte stream
Here are some bytes. I dont know what they mean.
Ill pass these to the app. It knows what to do.
TCP/IP
TCP/IP
8Socket
- How does one speak TCP/IP?
- Sockets provides interface to TCP/IP
- Generic interface for many protocols
9Socket Types
10Socket
- Identified by protocol and local/remote
address/port - Applications may refer to many sockets
- Socket abstraction
- Berkeley Sockets (traditional)
- Generic
- multiple families
- address representation independence)
- Uses existing I/O programming interface as much
as possible - Sockets work with Unix I/O services just like
files, pipes - Sockets have special needs
- establishing a connection
- specifying communication endpoint addresses
11TCP/IP Sockets
- mySock socket(family, type, protocol)
- TCP/IP-specific sockets
- Socket reference
- File (socket) descriptor in UNIX
- Socket handle in WinSock
12- struct sockaddr
-
- unsigned short sa_family / Address family
(e.g., AF_INET) / - char sa_data14 /
Protocol-specific address information / -
- struct sockaddr_in
-
- unsigned short sin_family / Internet
protocol (AF_INET) / - unsigned short sin_port / Port
(16-bits) / - struct in_addr sin_addr / Internet
address (32-bits) / - char sin_zero8 / Not used /
-
- struct in_addr
-
- unsigned long s_addr / Internet
address (32-bits) / -
Generic
IP Specific
sockaddr
Family
Blob
8 bytes
2 bytes
4 bytes
2 bytes
Family
sockaddr_in
Port
Not used
Internet address
13Clients and Servers
- Client Initiates the connection
- Server Passively waits to respond
Server Jane
Client Bob
Hi, Bob. Im Jane
Hi. Im Bob. Nice to meet you, Jane.
14Functions needed
- Specify local and remote communication endpoints
- Initiate a connection (client)
- Wait for incoming connection (server)
- Send and receive data
- Terminate a connection gracefully
- Error handling
15TCP Client/Server Interaction
Server starts by getting ready to receive
client connections
- Server
- Create a TCP socket
- Assign a port to socket
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
16Creating a Socket
- int socket(int family, int type, int proto)
- system call returns a socket descriptor(small
integer) -1 on error - allocates resources needed for a communication
endpoint - does not deal with endpoint addressing
- family specifies the protocol family
- AF_INET for TCP/IP
- type specifies the type of service(communication)
- SOCK_STREAM, SOCK_DGRAM
- protocol specifies the specific protocol
- usually 0 which means the default
17Declaration for socket function
18Specifying an Endpoint Address
- Remember that the sockets API is generic
- There must be a generic way to specify endpoint
addresses - TCP/IP requires an IP address and a port number
for each endpoint address. - Other protocol suites(families) may use other
schemes. - Generic socket addresses(The C function that make
up the sockets API expect structures of type
sockaddr.) - struct sockaddr
- unsigned short sa_family
//specifies the address type - char sa_data14
//specifies the address value -
19Assigning an address to a socket
- int bind(int socket, (struct sockaddr ) address,
int address_length) - The bind() system call is used to assign an
address to an existing socket. - bind returns 0 if successful or -1 on error
- Example
- struct sockaddr_in sin
- int s
- s socket(AF_INET, SOCK_DGRAM, 0)
- sin.sin_family AF_INET
- sin.sin_port htons(9999)
- sin.sin_addr.s_addr INADDR_ANY
- bind(s, (struct sockaddr )sin, sizeof(sin))
20listen() connect() -- TCP Sockets
- int listen(int socket, int qlength)
- allows servers to prepare a socket for incoming
connections - puts the socket in a passive mode ready to accept
connections - informs the OS that the protocol software should
enqueue multiple simultaneous requests that
arrive at the socket - applies only to sockets that have selected
reliable stream delivery service - int connect(int, struct sockaddr dest_addr,
int) - binds a permanent destination to a socket
- changes the socket state from unconnected state
to connected state - The semantics of connect depend on the
underlaying protocol - TCP connection (AF_INET, reliabe stream delivery
service) - just store the destination address locally
(connectionless)
21accept() -- TCP Sockets
- int accept(int, struct sockaddr addr, int
addrlen) - needs to wait for a connection
- blocks until a connection request arrives
- addrlen is a pointer to an integer
- when a request arrives, the system fills in
argument addr with the address of the client that
has placed the request and sets addrlen to the
length of the address. - system creates a new socket, returns the new
socket descriptor
22send() and recv() -- TCP Sockets
- int send(int s, const char msg, int len, int
flags) - connected socket
- argument flags controls the transmission.
- allows the sender to specify that the message
should be sent out-of- band messages correspond
to TCPs urgent data - allows the caller to request that the message be
sent without using local routine tables (take
control of routine) - int recv(int s, char buf, int len, int flags)
- connected socket
- argument flags allow the caller to control the
reception - look ahead by extracting a copy of the next
incoming message without removing the message
from the socket
23close() and shutdown()
- close(int socket)
- For UDP sockets, this will release the ownership
on the local port that is bound to this socket - For TCP, this will initiate a two-way shutdown
between both hosts before giving up port
ownership. - shutdown(int socket, int how)
- f the how field is 0, this will disallow further
reading (recv) from the socket. - If the how field is 1, subsequent writes (send)
will be disallowed. The socket will still need to
be passed to close.
24Relationship Between Sockets and File Descriptors
- Socket handles are integer values. In UNIX,
socket handles can be passed to most of the
low-level POSIX I/O functions. - read(s, buffer, buff_length) //s could be a
file descriptor too - write(s, buffer, buff_length)
- Calling read on an open socket is equivalent to
recv - if the socket is UDP, then information about the
sender of the datagram will not be returned - Similarly the write function call is equivalent
to send - UDP sockets may call connect to use send and
write - use the socket library functions instead of the
file I/O equivalents.
25Socket interface for Connectionless Iterative
Server
26TCP Client/Server Interaction
/ Create socket for incoming connections
/ if ((servSock socket(PF_INET,
SOCK_STREAM, IPPROTO_TCP)) lt 0)
DieWithError("socket() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
27TCP Client/Server Interaction
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 / if (bind(servSock,
(struct sockaddr ) echoServAddr,
sizeof(echoServAddr)) lt 0)
DieWithError("bind() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
28TCP Client/Server Interaction
/ Mark the socket so it will listen for
incoming connections / if (listen(servSock,
MAXPENDING) lt 0) DieWithError("listen()
failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
29TCP Client/Server Interaction
for () / Run forever / clntLen
sizeof(echoClntAddr) if ((clntSockaccept(se
rvSock,(struct sockaddr )echoClntAddr,clntLen))
lt 0) DieWithError("accept() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
30TCP Client/Server Interaction
Server is now blocked waiting for connection
from a client Later, a client decides to talk to
the server
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
31TCP Client/Server Interaction
/ Create a reliable, stream socket using
TCP / if ((sock socket(PF_INET,
SOCK_STREAM, IPPROTO_TCP)) lt 0)
DieWithError("socket() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
32TCP Client/Server Interaction
echoServAddr.sin_family AF_INET
/ Internet address family /
echoServAddr.sin_addr.s_addr inet_addr(servIP)
/ Server IP address / echoServAddr.sin_port
htons(echoServPort) / Server port /
if (connect(sock, (struct sockaddr )
echoServAddr, sizeof(echoServAddr)) lt 0)
DieWithError("connect() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
33TCP Client/Server Interaction
if ((clntSockaccept(servSock,(struct sockaddr
)echoClntAddr,clntLen)) lt 0)
DieWithError("accept() failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
34TCP Client/Server Interaction
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")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
35TCP Client/Server Interaction
/ Receive message from client / if
((recvMsgSize recv(clntSocket, echoBuffer,
RCVBUFSIZE, 0)) lt 0) DieWithError("recv()
failed")
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
36TCP Client/Server Interaction
close(sock)
close(clntSocket)
- Server
- Create a TCP socket
- Bind socket to a port
- Set socket to listen
- Repeatedly
- Accept new connection
- Communicate
- Close the connection
- Client
- Create a TCP socket
- Establish connection
- Communicate
- Close the connection
37TCP Tidbits
- Client must know the servers address and port
- Server only needs to know its own port
- No correlation between send() and recv()
- Client
- send(Hello Bob)
- recv() -gt Hi Jane
- Server
- recv() -gt Hello
- recv() -gt Bob
- send(Hi )
- send(Jane)
38Closing a Connection
- close() used to delimit communication
- Analogous to EOF
- Echo Client
- send(string)
- while (not received entire string)
- recv(buffer)
- print(buffer)
- close(socket)
- Echo Server
- recv(buffer)
- while(client has not closed connection)
- send(buffer)
- recv(buffer)
- close(client socket)
39Byte-order Transformations
- Byte ordering is a function of machine
architecture - Intel little-endian
- Sparc, PowerPC big-endian
- Network order big-endian
- The byte order for the TCP/IP protocol suite is
big endian.
40Big-endian byte order
41Little-endian byte order
42Network Byte Order Functions
43Network Byte Order Functions
- Functions
- u_long m ntohl(u_long m)
- network-to-host byte order, 32 bit
- u_long m htonl(u_long m)
- host-to-network byte order, 32 bit
- ntohs(),htons()
- short (16 bit)
- Example
- struct sockaddr_in sin
- sin.sin_family AF_INET
- sin.sin_port htons(9999)
- sin.sin_addr.s_addr inet_addr
44Address transformation
struct in_addr
char
45Address transformation
- char inet_ntoa(struct in_addr ip)
- Converts the 32-bit value which is assumed to be
in network byte order and contained in ip to a
string - The pointer returned by inet_ntoa contains this
string. However, subsequent calls to inet_ntoa
will always return the same pointer, so copying
the string to another buffer is recommended
before calling again. - unsigned int inet_addr(char str)
- str represents an IP address(dotted-quad
notation) inet_addr will return it's equivalent
32-bit value in network byte order. - This value can be passed into the sin_addr.s_addr
field of a socketaddr_in structure - Ex. sin_addr inet_addr(152.14.51.129)
- -1 is returned if the string can not be
interpreted
46Obtaining Information About Hosts, etc.
- struct hostent hptr /includes host address in
binary/ - hptrgethostbyname(char name)
- Ex.gethostbyname(www.csc.ncsu.edu)
- Struct hostent hptr
- hptrgethostbyaddr(char addr,int addrlen, int
addrtype) - Ex gethostbyaddr(addr, 4, AF_INET)
47Obtaining Information About Hosts, etc.
- int inet_addr(char dotdecimal)
- Ex. sin_addr inet_addr(152.14.51.129)
- struct servent sptr / includes port and
protocol / - sptrgetservbyname(char name, char proto)
- Ex. getservbyname(smtp, tcp)
- struct protoent pptr / includes protocol
number / - pptrgetprotobyname(char name)
- Ex. getprotobyname(tcp)
48Others
- Include files
- include ltsys/types.hgt
- include ltsys/socket.hgt
- include ltnetinet/in.hgt
- include ltarpa/inet.hgt
- include ltnetdb.hgt
- include ltunistd.hgt
- include ltsignal.hgt
- include ltstdio.hgt
- include ltfcntl.hgt
- include lterrno.h
- include ltsys/time.hgt
- include ltstdlib.hgt
- include ltmemory.hgt
- Compiling and Linking
- Under most versions of UNIX (Linux, BSD, SunOS,
IRIX) compiling is done as usual - gcc my_socket_program.c -o my_socket_program
- Solaris
- cc my_socket_program.c -o my_socket_program
-lsocket -lnsl
49Summary
- TCP/IP basic
- UNIX/C Sockets
- socket() bind() connect() listen()
accept() sendto() recvfrom() send() recv()
read() write() - some utility functions
- For more Information
- W. Richard Stevens, Unix Network Programming
Networking APIs Sockets and XTI, Volume 1,
Second Edition, Prentice Hall, 1998. - THE network programming bible.