Socket Programming
Socket Programming
Socket Programming
Resources:
1. PC 2
2. NICs 2
3. Hub 1
4. data cables 2
TCP:
TCP is a transport layer protocol used by applications that require guaranteed delivery. It is a
sliding window protocol that provides handling for both timeouts and retransmissions. TCP
establishes a full duplex virtual connection between two endpoints. Each endpoint is defined by an
IP address and a TCP port number. The operation of TCP is implemented as a finite state machine.
The byte stream is transferred in segments. The window size determines the number of bytes of
data that can be sent before an acknowledgement from the receiver is necessary.
UDP:
The User Datagram Protocol offers only a minimal transport service -- non-guaranteed datagram
delivery and gives applications direct access to the datagram service of the IP layer. UDP is used
by applications that do not require the level of service of TCP or that wish to use communications
services (e.g., multicast or broadcast delivery) not available from TCP. UDP is almost a null
protocol; the only services it provides over IP are checksumming of data and multiplexing by port
number. Therefore, an application program running over UDP must deal directly with end-to-end
communication problems that a connection-oriented protocol would have handled – e.g.,
retransmission for reliable delivery, packetization and reassembly, flow control, congestion
avoidance, etc., when these are required. The fairly complex coupling between IP and TCP will be
mirrored in the coupling between UDP and many applications using UDP.
Socket:
1). Stream sockets: They are connection oriented reliable sockets also called TCP sockets.
2). Datagram sockets: They are connectionless unreliable sockets also called UDP sockets.
Notice also that once a connection is established, both sides can send and receive information.
The system calls for establishing a connection are somewhat different for the client and the server,
but both involve the basic construct of a socket.
A socket is one end of an interprocess communication channel. The two processes
each establish their own socket.
The steps involved in establishing a socket on the client side are as follows:
1. Create a socket with the socket() system call
2. Connect the socket to the address of the server using the connect() system call.
3. Send and receive data. There are a number of ways to do this, but the simplest is to use
the read() and write() system calls.
The steps involved in establishing a socket on the server s ide are as follows:Create a socket with the
socket() system call
1. Bind the socket to an address using the bind() system call. For a server socket on
the Internet, an address consists of a port number on the host machine.
2. Listen for connections with the listen() system call
3. Accept a connection with the accept() system call. This call typically blocks until a
client connects with the server.
Send and receive data.
Stages of Server:
● socket creation:
int sockfd = socket(domain, type, protocol)
● Setsockopt:
i nt setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
This helps in manipulating options for the socket referred by the file descriptor sockfd. This is
completely optional, but it helps in reuse of address and port. Prevents error such as: “address
already in use”
● Bind:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
After creation of the socket, bind function binds the socket to the address and
port number specified in addr(custom data structure). In the example code, we
bind the server to the localhost, hence we use INADDR_ANY to specify the IP
address.
● Listen:
int listen(int sockfd, int backlog);
It puts the server socket in a passive mode, where it waits for the client to approach the server
to make a connection. The backlog, defines the maximum length to which the queue of
pending connections for sockfd may grow. If a connection request arrives when the queue is
full, the client may receive an error with an indication of ECONNREFUSED.
● Accept:
int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
It extracts the first connection request on the queue of pending connections for the listening
socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to
that socket. At this point, connection is established between client and server, and they are
ready to transfer data.
Necessary Functions :
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
Send a message on the socket
Arguments :
sockfd – File descriptor of socket
buf – Application buffer containing the data to be sent
len – Size of buf application buffer
flags – Bitwise OR of flags to modify socket behaviour
dest_addr – Structure containing address of destination
addrlen – Size of dest_addr structure
Multithreading in C
What is a Thread?
A thread is a single sequence stream within in a process. Because threads have some of the properties of
processes, they are sometimes called lightweight processes.
Why Multithreading?
Threads are popular way to improve application through parallelism. For example, in a browser,
multiple tabs can be different threads. MS word uses multiple threads, one thread to format the text,
other thread to process inputs, etc.
Threads operate faster than processes due to following reasons:
1) Thread creation is much faster.
2) Context switching between threads is much faster.
3) Threads can be terminated easily
4) Communication between threads is faster.
Pthread library is used to perform multithreading in C.
Functions in Pthread;
Study simple client-server hello message program of TCP and UDP. Compile and run the program
and understand output.
Exercise-1b:
Study multithread sample code. Compile and run the program and understand output.
Exercise-2a:
Exercise-2b:
Multithreaded server:
Extend the application you have designed in Exercise 2a such that server can handle multiple
clients in parallel. Use multithreading.
[Hint:https://dzone.com/articles/parallel-tcpip-socket-server-with-multi-threading]
Exercise-2c:
Implement a scenario in which there is one server (PC1) which can handle multiple clients (using
multithreading implemented in exercise 2b) and one client (PC2). Server is supposed to send a file of
50Mb for each request. Client (PC2) can send multiple requests (by generating multiple threads) for
the same file.
● Find the time required to transfer file for each request of client. (Hint: Use time function used
in linux shell https://www.faqforge.com/linux/determine-execution-time-command-linux/ )
● Change the number of requests generated from 1to 10. Create a table for time required to
transfer file to any one client(fixed) for different number of requests.
● Plot a graph of time required to transfer file for any one client(fixed) vs. different number of
requests.
Exercise 2d:
Implement a scenario in which two clients are supposed to access the same file at the server. Provide a locking
mechanism which prevents them to access the file at the same time.(Hint: Use code with mutex and locking
mechanism from reading material )
Exercise 3:
Goal of this exercise is to implement a scenario where all the clients of the server receives the file at the same
time. (Such as online game or stock market etc)
Implement a scenario in which there is one server and multiple clients.
Clients send request to get a file(50Mb) from server. Server sends the file with timestamp( T ms ) and
ΔT . When client receives file(at time T mr ) it holds file till ( ΔT -( T ms - T mr )) time. After that it
displays file. If the client receives file after ΔT then it sends request to server to update value of ΔT .
Submission:
Submit a zip file containg all the codes the naming convention should be as following: