Sockets
Background
TCP: connection-oriented, makes sure data is delivered, sends packets again and again until everything is received, sends acknowledgments that data is received
UDP: connectionless, does not guarantee delivery
In the IP world:
IP address is a 32-bit address that we usually write in 4 numbers separated by dots:
18.0.2.231
Host name is a name that maps to an IP address that makes it easier to remember an address. Hostname web is the name of a web host in the mit.edu domain: web.mit.edu is the full name that maps to IP address: 18.69.0.38.
To find this address, you can for example type at the athena prompt:
athena% ping -s list.mit.edu 3 1
(where 3 is the number of bytes sent, and 1 is the number of times this request is sent)
PING list.mit.edu: 3 data bytes
11 bytes from LIST.MIT.EDU (18.58.0.236): icmp_seq=0.
...
Let us also define the concept of port. A port is an integer number that accompanies a networked application that lets it communicate independently of the other networked applications. For example, if you have a web server, it usually sits at port 80 for incoming requests. This server will not interfere with, say an FTP server on the same machine that is listening to port 21.
Introduction to Sockets
Basically, we need to send and receive data between two different hosts. The process of receiving and sending that data is Input/Output or I/O. The process of sending and receiving data over a network is called network I/O. Sockets constitute an interface to enable network I/O. File I/O based on the UNIX open-read-write-close is neither flexible nor complete enough to allow good network I/O
Problems with that paradigm include:
No standard way devised for this I/O but a de facto interface: sockets.
Sockets independent of network technology and therefore work with several network protocol families:
TCP/IP (PF_INET),
AppleTalk (PF_APPLETALK),
Unix file system (PF_UNIX)
They allow different types of data to be transmitted:
SOCK_STREAM (e.g. Web access),
SOCK_DGRAM (e.g. Real Audio and Real Video),
SOCK_RAW (bit access)
Can specify the protocol. For example, {PF_INET, SOCK_STREAM} defines TCP and {PF_INET, SOCK_DGRAM} defines UDP.
Sockets are used in most networked applications.
Steps in building a client-server architecture:
Here we are discussing the client/server architecture using TCP.
A server in a networked application is a program that sits on one host and listens passively for incoming traffic at a certain port.
The web server sits web.mit.edu listens to port 80 or in other words (18.69.0.38:80).
The client sits at the other end and is active. It send connection requests, writes data, receives data and closes the connection.
When a server receives an incoming connect request, it answers by an accept, reads incoming data and writes outgoing data. It also closes the socket once the communication is finished.
Client Side |
Server Side |
create: socket() |
create: socket() |
|
bind() |
|
listen() |
connect() |
accept() |
read()/write() |
read()/write() |
close() |
close() |
Note: all example code in provided in C, but you can also use any other language that provides a socket library.
int socket (int domain, int type, int protocol)
e.g.
client_socket = socket (PF_INET, SOCK_STREAM, 0);
server_socket = socket (PF_INET, SOCK_STREAM, 0);
client_socket and server_socket will be set to a negative number if no socket was created, positive or null otherwise
int connect (int socket, struct sockaddr* destaddr, int addrlen)
e.g.
connect (client_socket, &server_address, sizeof (server_address));
server_address is a structure that contains information about the server you are building, what port it listens to, what clients can connect to the server and what protocol is used:
bzero(&server_address, sizeof(server_address)); // reset it
server_address.sin_family = AF_INET; // internet protocol family
server_address.sin_addr.s_addr = htonl(INADDR_ANY); // all addresses welcome
server_address.sin_port = htons(PORT); // PORT is an integer e.g. 5501
In the case of a server application, 3 steps:
bind (socket, localaddr, addrlen)
// establishes a local address for the socket
listen (socket, backlog)
// puts a socket in a passive mode, ready to accept a number (backlog) of connections at a time
accept (socket, address, addrlen)
// waits then accepts connection requests
// address refers to the address of the client that has placed a request
int write (int socket, char* buffer, int length)
e.g. write (server_socket, buffer, 1);
in this case server should have:
int read (int socket, char* buffer, int length)
e.g. read (client_socket, buffer, 1);
or vice versa
close (socket)
e.g.
close (client_socket)
Important and Helpful functionality
How to look up a host by its name:
gethostbyname(host)
How to look up a host by its address:
gethostbyaddr(address, length, type)
where length = sizeof(address) and type = AF_INET
In order to use connectionless service, such as UDP, one can use recvfrom() and sendto() instead of read() and write().
recvfrom() and writeto() are usually associated with connectionless traffic though because both source address is always sent with the data.
recvfrom(socket, buffer, length, flags, address, &addrlen);
To find about the functionality of a certain command (function), type at the athena prompt, the man command followed by the function name:
athena% man gethostbyname
will give help information on gethostbyname()
Client and Server files
tcpechoclient.c
tcpechoserver.c
To compile on athena, save the files locally. Afterwards, execute from the athena prompt:
athena% gcc tcpechoclient.c -lsocket -o tcpechoclient
athena% gcc tcpechoserver.c -lsocket -o tcpechoserver
To run on athena, open a new xterm by typing:
athena% xterm &
In one of the xterms, you can run the server by typing:
athena% tcpechoserver
In the other xterm, run the client:
athena% tcpechoclient (server IP address)
where server IP address can be found by executing ping as mentioned earlier
Homework available at this link: homework.txt