The services provided (often by the operating
system) that provide the interface between
application and protocol software.
ApplicationApplication
Network APINetwork API
Protocol AProtocol AProtocol BProtocol BProtocol CProtocol C
Definition
Why do we need sockets?
Provides an abstraction for inter process
communication
An end-point for an Internet network connection
what the application layer “plugs into”
User Application
Socket
Operating System
Transport Layer
Internet Protocol Layer
User sees “descriptor” - integer index or object handle
like: FILE *, or file index from open()
returned by socket() call (more later)
programmer cares about Application Programming Interface (API)
Socket Basics
End point determined by two things:
Host address: IP address is Network Layer
Port number: is Transport Layer
Two end-points determine a connection: socket pair
ex: 206.62.226.35,p21 + 198.69.10.2,p1500
ex: 206.62.226.35,p21 + 198.69.10.2,p1499
Socket Basics
Numbers (typical, since vary by OS):
0-1023 “reserved”, must be root
1024 - 5000 “ephemeral”
Above 5000 for general use
(50,000 is specified max)
Well-known, reserved services (see /etc/services in
Unix):
ftp 21/tcp
telnet 23/tcp
finger 79/tcp
snmp 161/udp
Ports
Functions
Define an “end- point” for communication
Initiate and accept a connection
Send and receive data
Terminate a connection gracefully
Examples
File transfer apps (FTP), Web browsers
(HTTP), Email (SMTP/ POP3), etc…
Types of Sockets
Two different types of sockets :
–stream vs. datagram
Stream socket :( a. k. a. connection- oriented socket)
–It provides reliable, connected networking service
–Error free; no out- of- order packets (uses TCP)
–applications: telnet/ ssh, http, …
Datagram socket :( a. k. a. connectionless socket)
–It provides unreliable, best- effort networking service
–Packets may be lost; may arrive out of order (uses UDP)
–applications: streaming audio/ video (realplayer), …
Addressing
Client Server
Addresses and Sockets
Structure to hold address information
Functions pass address from user to OS
bind()
connect()
sendto()
Functions pass address from OS to user
accept()
recvfrom()
struct in_addr {
in_addr_t s_addr; /* 32-bit IPv4 addresses */
};
struct sockaddr_in {
unit8_t sin_len; /* length of structure */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* TCP/UDP Port num */
struct in_addr sin_addr; /* IPv4 address (above) */
char sin_zero[8]; /* unused */
}
Are also “generic” and “IPv6” socket structures
Socket Address Structure
Addresses, Ports and Sockets
Like apartments and mailboxes
You are the application
Your apartment building address is the address
Your mailbox is the port
The post-office is the network
The socket is the key that gives you access to the right
mailbox
Client – high level view
Create a socket
Setup the server address
Connect to the server
Read/write data
Shutdown connection
int connect_ socket( char *hostname, int port) {
int sock;
struct sockaddr_in sin;
struct hostent *host;
sock = socket( AF_ INET, SOCK_ STREAM, 0);
if (sock == -1)
return sock;
host = gethostbyname( hostname);
if (host == NULL) {
close( sock);
return -1;
}
memset (& sin, 0, sizeof( sin));
sin. sin_ family = AF_ INET;
sin. sin_ port = htons( port);
sin. sin_ addr. s_ addr = *( unsigned long *) host-> h_ addr_ list[
0];
if (connect( sock, (struct sockaddr *) &sin, sizeof( sin)) != 0) {
close (sock);
return -1;
}
return sock;
}
Resolve the host
struct hostent *gethostbyname( const char *hostname);
/*Return nonnull pointer if OK, NULL on error */
Setup up the struct
unit16_t htons(unit16_t host16bitvaule)
/*Change the port number from host byte order to
network byte order */
Connect
connect(int socketfd, const struct sockaddr * servaddr,
socket_t addrlen)
/*Perform the TCP three way handshaking*/
Hostent structure
struct hostent{
char * h_name /*official name of host*/
char ** h_aliases; /* pointer ot array of\
pointers to alias name*/
int h_addrtype /* host address type*/
int h_length/* length of address */
char ** h_addr_list/*prt to array of ptrs with \
IPv4 or IPv6 address*/
}
Ipv4 socket address structure
struct socketaddr_in{
uint8_t sin_len; /*length of the structure (16)*/
sa_falimily_t sin_family /* AF_INT*/
in_port_t sin_port /* 16 bit TCP or UDP port number*/
struct in_addr sin_addr/* 32 bit Ipv4 address */
char sin_zero(8)/* unused*/
}
Make the socket
Socket(int family , int type, in t protocol);
return nonnegative value for OK, -1 for error
Server – high level view
Create a socket
Bind the socket
Listen for connections
Accept new client connections
Read/write to client connections
Shutdown connection
Listening on a port (TCP)
int make_ listen_ socket( int port) {
struct sockaddr_ in sin;
int sock;
sock = socket( AF_ INET, SOCK_ STREAM, 0);
if (sock < 0)
return -1;
memset(& sin, 0, sizeof( sin));
sin. sin_ family = AF_ INET;
sin. sin_ addr. s_ addr = htonl( INADDR_ ANY);
sin. sin_ port = htons( port);
if (bind( sock, (struct sockaddr *) &sin, sizeof( sin)) <
0)
return -1;
return sock;
}
Make the socket
Setup up the struct
Bind
bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen);
/* return 0 if OK, -1 on error
assigns a local protocol adress to a socket*/
Accepting a client connection (TCP)
int get_ client_ socket( int listen_ socket) {
struct sockaddr_ in sin;
int sock;
int sin_ len;
memset(& sin, 0, sizeof( sin));
sin_ len = sizeof( sin);
sock = accept( listen_ socket, (struct sockaddr *)
&sin, &sin_ len);
return sock;
}
Setup up the struct
Accept the client connection
accept(int sockefd, struct sockaddr * claddr, socklen_t * addrlen)
/* return nonnegative descriptor if OK, -1 on error
return the next completed connection from the front of the
completed connection queue.
if the queue is empty,
the process is put to sleep(assuming blocking socket)*/
Sending / Receiving Data
•With a connection (SOCK_STREAM):
–int count = send(sock, &buf, len, flags);
•count: # bytes transmitted (-1 if error)
•buf: char[], buffer to be transmitted
•len: integer, length of buffer (in bytes) to transmit
•flags: integer, special options, usually just 0
–int count = recv(sock, &buf, len, flags);
•count: # bytes received (-1 if error)
•buf: void[], stores received bytes
•len: # bytes received
•flags: integer, special options, usually just 0
–Calls are blocking [returns only after data is sent (to
socket buf) / received]
Connection-oriented example (TCP)
Server
Socket()
Bind()
Client
Socket()
Listen()
Accept()
Recv()
Send()
Connect()
Send()
Recv()
Block until
connect
Process
request
Connection Establishmt.
Data (request)
Data (reply)
CS 640 20
Connectionless example (UDP)
Server
Socket()
Bind()
Client
Socket()
Recvfrom()
Sendto()
Bind()
Sendto()
Recvfrom()
Block until
Data from
client
Process
request
Data (request)
Data (reply)
Socket call
•Means by which an application attached to the network
•int socket(int family, int type, int protocol)
•Family: address family (protocol family)
–AF_UNIX, AF_INET, AF_NS, AF_IMPLINK
•Type: semantics of communication
–SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
–Not all combinations of family and type are valid
•Protocol: Usually set to 0 but can be set to specific value.
–Family and type usually imply the protocol
•Return value is a handle for new socket
Bind call
Binds a newly created socket to the specified address
Int bind(int socket, struct sockaddr *address, int addr_len)
Socket: newly created socket handle
Address: data structure of address of local system
IP address and port number (demux keys)
Same operation for both connection-oriented and
connectionless servers
•Can use well known port or unique port
Used by connection-oriented servers to indicate an application
is willing to receive connections
Int(int socket, int backlog)
Socket: handle of newly creates socket
Backlog: number of connection requests that can be queued
by the system while waiting for server to execute accept call.
Listen call
After executing listen, the accept call carries out a passive open
(server prepared to accept connects).
Int accept(int socket, struct sockaddr *address, int addr_len)
It blocks until a remote client carries out a connection request.
When it does return, it returns with a new socket that
corresponds with new connection and the address contains the
clients address
Accept call
Client executes an active open of a connection
Int connect(int socket, struct sockaddr *address, int
addr_len)
Call does not return until the three-way handshake (TCP)
is complete
Address field contains remote system’s address
Client OS usually selects random, unused port
Connect call
After connection has been made, application uses send/recv to data
Int send(int socket, char *message, int msg_len, int flags)
Send specified message using specified socket
Int recv(int scoket, char *buffer, int buf_len, int flags)
Receive message from specified socket into specified buffer
Send(to), Recv(from)
Dealing with blocking calls
Many functions block
accept(), connect(),
All recv()
For simple programs this is fine
What about complex connection routines
Multiple connections
Simultaneous sends and receives
Simultaneously doing non-networking processing
Dealing with blocking (cont..)
Options
Create multi-process or multi-threaded code
Turn off blocking feature (fcntl() system call)
Use the select() function
What does select() do?
Can be permanent blocking, time-limited blocking or non-
blocking
Input: a set of file descriptors
Output: info on the file-descriptors’ status
Therefore, can identify sockets that are “ready for use”: calls
involving that socket will return immediately
Select function call
Int status = select()
Status: # of ready objects, -1 if error
nfds: 1 +largest file descriptor to check
readfds: list of descriptors to check if read-ready
writefds: list of descriptors to check if write-ready
exceptfds: list of descriptors to check if an exception is
registered
Timeout: time after which select returns
Protocol implementation
Process per protocol
Use a separate process to implement each protocol
Messages are passes between processes
Process per message
Use one process to handle each message/communication
Generally more efficient
Buffer use
Applications use buffers as do protocols
Copies are VERY expensive
Message abstraction enables pointers to be used and
minimal copies
Socket Implementation
You have to be very careful when using these calls
Specific data structures and formats
Ports cannot be less than 1024
You can use other tools to see if things are working
Tcpdump
/proc
netstat
Client and server can be on same system
Think about error handling methods
Practical issues – using sockets