0% found this document useful (0 votes)
391 views

Lab 4 - TCP, UDP - 2020 PDF

This document provides instructions for a lab assignment on implementing client-server applications using UDP and TCP protocols. It begins with objectives of understanding client-server communication and using sockets in C programming. Background information is provided on TCP vs UDP protocols. Code snippets show how to create and bind sockets, send/receive data for UDP client and server applications to demonstrate a simple echo protocol. Students are asked to complete tasks individually, provide code and output, and avoid plagiarism.

Uploaded by

xyz
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
391 views

Lab 4 - TCP, UDP - 2020 PDF

This document provides instructions for a lab assignment on implementing client-server applications using UDP and TCP protocols. It begins with objectives of understanding client-server communication and using sockets in C programming. Background information is provided on TCP vs UDP protocols. Code snippets show how to create and bind sockets, send/receive data for UDP client and server applications to demonstrate a simple echo protocol. Students are asked to complete tasks individually, provide code and output, and avoid plagiarism.

Uploaded by

xyz
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Department of Computing

EE353: Computer Networks


Class: BESE-9B
CLO 1: Understand the fundamental Building blocks of Computer
Networks i.e., Layered approach and protocols that make
networking possible
Lab 4: Implement simple Client / Server applications using UDP
and TCP
Date: 10-2-2020

Time: 9:00 to 12:00


Instructor: Dr. Muhammad Zeeshan
Lab Engineer: Syed Muhammad Ali Musa

EE353: Computer Networks Page 1


Lab 4: Implement simple Client / Server applications using UDP and TCP

1.0 Objectives:

After this lab, the students should be able to

• Explain the concepts of client server communication


• Setup client/server communication
• Use the sockets interface of C programming language
• Implement simple Client / Server applications using UDP and TCP

2.0 Instructions:

• Read carefully before starting the lab.

• These exercises are to be done individually.

• To obtain credit for this lab, you are supposed to complete the lab tasks and provide
the source codes and the screen shot of your output in this document (please use
red font color) and upload the completed document to your course’s LMS site.

• Avoid plagiarism by copying from the Internet or from your peers. You may refer to
source/ text but you must paraphrase the original work.

3.0 Background:
4.0 Client-Server Socket Programming

We introduce UDP and TCP socket programming by way of a simple UDP application
and a simple TCP application both implemented in Python.

We’ll use the following simple ‘Echo’ client-server application to demonstrate socket
programming for both UDP and TCP:

1. The client reads a line of characters (data) from its keyboard and sends the data to
the server.

2. The server receives the data .

EE353: Computer Networks Page 2


3. The server sends the modified data to the client.

4. The client receives the modified data and displays the line on its screen.

What is the difference between TCP & UDP protocols of TCP/IP


protocol suite.
The 2 types of traffic in the network are based on TCP (Transmission
Control Protocol) and UDP (User Datagram Protocol). Following are the
differences between the two

• TCP is connection Oriented protocol, hence a connection need to be


established (using 3-way handshaking) before data is transmitted
using TCP. UDP is Connectionless protocol and no connection need
to be established. The packets are sent directly over the network.

• Because connection need to be established, TCP data transfer takes


more time (3-way handshaking is done for establishing connection
and then for removing the connection) than data transferred using
UDP.

EE353: Computer Networks Page 3


• Connection in the TCP is established to make the transfer reliable
(acknowledgement based). Hence data transfer using TCP is reliable
and UDP is non-reliable (sender does no know, for sure, if the packet
has actually reached the receiver or not).

• Header Size of a TCP packet is bigger than the UDP header.

• TCP does the error checking also, UDP does not have an option for
Error checking.

• Packets are ordered in case of TCP (i.e they are received in the
same order as they are sent). 7. Application layer protocols like
HTTP, FTP, Telnet, etc. uses TCP to transmit data whereas UDP is
used by protocols like VoIP, DHCP, SNMP, etc.

Figure 2 TCP vs UDP Flow

4.1 Socket programming using UDP

Figure 2 highlights the main socket-related activity of the client and server that
communicate over the UDP transport service.

Now let’s take a look at the client-server program pair for a UDP implementation of this

EE353: Computer Networks Page 4


simple application. We’ll begin with the UDP client, which will send a simple application-
level message to the server. In order for the server to be able to receive and reply to the
client’s message, it must be ready and running— that is, it must be running as a
process before the client sends its message.

The client program is called UDPClient.c, and the server program is called
UDPServer.c. In order to emphasize the key issues, we intentionally provide code that
is minimal. “Good code” would certainly have a few more auxiliary lines, in particular for
handling error cases.

Socket API defines a generic data type for addresses:

Particular form of the sockaddr used for TCP/IP addresses:


Important: sockaddr_in can be casted to a sockaddr
struct sockaddr {
unsigned short sa_family; /* Address family (e.g. AF_INET) */
char sa_data[14]; /* Family-specific address information */
}
struct in_addr {
unsigned long s_addr; /* Internet address (32 bits) */
}
struct sockaddr_in {
unsigned short sin_family; /* Internet protocol (AF_INET) */
unsigned short sin_port; /* Address port (16 bits) */
struct in_addr sin_addr; /* Internet address (32 bits) */
char sin_zero[8]; /* Not used */
}

Socket creation in C

int sockid = socket(family, type, protocol);


sockid: socket descriptor, an integer (like a file-handle)
family: integer, communication domain, e.g.,
PF_INET, IPv4 protocols, Internet addresses (typically used)
PF_UNIX, Local communication, File addresses
type: communication type
SOCK_STREAM - reliable, 2-way, connection-based service
SOCK_DGRAM - unreliable, connectionless, messages of maximum length
protocol: specifies protocol „ IPPROTO_TCP IPPROTO_UDP usually set to 0 (i.e., use
default protocol), upon failure returns -1
NOTE: socket call does not specify where data will be coming from,nor where it will be
going to – it just creates the interface!

Closing a socket

EE353: Computer Networks Page 5


status = close(sockid);
sockid: the file descriptor (socket being closed)
status: 0 if successful, -1 if error

Associates and reserves a port for use by the socket

int status = bind(sockid, &addrport, size);


sockid: integer, socket descriptor
addrport: struct sockaddr, the (IP) address and port of the machine for TCP/IP server,
internet address is usually set to INADDR_ANY, i.e.,chooses any incoming interface
size: the size (in bytes) of the addrport structure
status: upon failure -1 is returned

Exchanging data with datagram socket


int count = sendto(sockid, msg, msgLen, flags, &foreignAddr, addrlen);
msg: const void[], message to be transmitted
msgLen: integer, length of message (in bytes) to transmit
flags: integer, special options, usually just 0
foreignAddr: struct sockaddr, address of the destination
addrLen: sizeof(foreignAddr)

int count = recvfrom(sockid, recvBuf, bufLen, flags, &clientAddr, addrlen);


recvBuf: void[], stores received bytes
bufLen: # bytes received
flags: integer, special options, usually just 0
clientAddr: struct sockaddr, address of the client
addrLen: sizeof(clientAddr)
Note:Calls are blocking , returns only after data is sent / received

Let’s put everything together


UDPClient.c
==================================================================
=========
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
int main() {
const char* server_name = "localhost";
EE353: Computer Networks Page 6
const int server_port = 8877;
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// creates binary representation of server name
// and stores it as sin_addr
inet_pton(AF_INET, server_name, &server_address.sin_addr);
// htons: port in network order format
server_address.sin_port = htons(server_port);
// open socket
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("could not create socket\n");
return 1;
}
// data that will be sent to the server
const char* data_to_send = " Hi BSCS 9";
// send data
int len =
sendto(sock, data_to_send, strlen(data_to_send), 0,
(struct sockaddr*)&server_address, sizeof(server_address));
// received echoed data back
char buffer[100];
recvfrom(sock, buffer, len, 0, NULL, NULL);
buffer[len] = '\0';
printf("recieved: '%s'\n", buffer);
// close the socket
close(sock);
return 0;
}
=========================================================
=======
UDPServer.c
=========================================================
=======
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>

EE353: Computer Networks Page 7


#include <string.h>
int main(int argc, char *argv[]) {
// port to start the server on
int SERVER_PORT = 8877;
socklen_t client_address_len;
// socket address used for the server
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// htons: host to network short: transforms a value in host byte
// ordering format to a short value in network byte ordering format
server_address.sin_port = htons(SERVER_PORT);
// htons: host to network long: same as htons but to long
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
// create a UDP socket, creation returns -1 on failure
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("could not create socket\n");
return 1;
}
// bind it to listen to the incoming connections on the created server
// address, will return -1 on error
if ((bind(sock, (struct sockaddr *)&server_address,
sizeof(server_address))) < 0) {
printf("could not bind socket\n");
return 1;
}
// socket address used to store client address
struct sockaddr_in client_address;

// run indefinitely
while (true) {
char buffer[500];
// read content into buffer from an incoming client
int len = recvfrom(sock, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_address,
&client_address_len);
// inet_ntoa prints user friendly representation of the
// ip address
buffer[len] = '\0';

EE353: Computer Networks Page 8


printf("received: '%s' from client %s\n", buffer,
inet_ntoa(client_address.sin_addr));
// send same content back to the client ("echo")
sendto(sock, buffer, len, 0, (struct sockaddr *)&client_address,
sizeof(client_address));
}
return 0;
}
===============================================

4.1.1 Lab Task 1: A useful Python UDP client/server application.


Modify the UDPClient program such that the UDPClient is able to calculate
the Application level Round Trip Time (RTT) for the communication
between the Client and the Server. The Client should also print the time
when Request is send and time when the Reply is received in human
readable form.
Please paste your source code for your UDPclient and screen shot of the output for Lab
Task 1 here.

4.2 Socket programming using TCP


We use the same simple client-server application to demonstrate socket programming
with TCP: The client sends one line of data to the server, the server capitalizes the line
and sends it back to the client. Figure 2 highlights the main socket-related activity of the
client and server that communicate over the TCP transport service.

Let’s now take a look at the lines that differ significantly from UDPServer and
TCPClient.

EE353: Computer Networks Page 9


Instructs TCP protocol implementation to listen for connections„

int status = listen(sockid, queueLimit);


sockid: integer, socket descriptor
queuelen: integer, # of active participants that can “wait” for a connection
status: 0 if listening, -1 if error

Note:listen() is non-blocking: returns immediately .The listening socket (sockid) is never


used for sending and receiving is used by the server only as a way to get new sockets

The client establishes a connection with the server by calling connect()


int status = connect(sockid, &foreignAddr, addrlen);
sockid: integer, socket to be used in connection
foreignAddr: struct sockaddr: address of the passive participant
addrlen: integer, sizeof(name)
status: 0 if successful connect, -1 otherwise

Note:connect() is blocking
The server gets a socket for an incoming client connection by calling accept()
int s = accept(sockid, &clientAddr, &addrLen);
sockid: integer, the orig. socket (being listened on)
clientAddr: struct sockaddr, address of the active participant filled in upon return
addrLen: sizeof(clientAddr): value/result parameter must be set appropriately before call
adjusted upon return

Note:accept() is blocking: waits for connection before returning ‰ dequeues the next
connection on the queue for socket (sockid)

Sending and receiving data

int count = send(sockid, msg, msgLen, flags);


msg: const void[], message to be transmitted
msgLen: integer, length of message (in bytes) to transmit
flags: integer, special options, usually just 0
count: # bytes transmitted (-1 if error)

int count = recv(sockid, recvBuf, bufLen, flags);


recvBuf: void[], stores received bytes
bufLen: # bytes received
flags: integer, special options, usually just 0
count: # bytes received (-1 if error)

Note:Calls are blocking ‰ returns only afterdata is sent / received

EE353: Computer Networks Page 10


Let’s put everything together
TCPClient.c
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
int main() {
const char* server_name = "localhost";
const int server_port = 8877;
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// creates binary representation of server name
// and stores it as sin_addr
// http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html
inet_pton(AF_INET, server_name, &server_address.sin_addr);
// htons: port in network order format
server_address.sin_port = htons(server_port);
// open a stream socket
int sock;
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("could not create socket\n");
return 1;
}
// TCP is connection oriented, a reliable connection
// **must** be established before any data is exchanged
if (connect(sock, (struct sockaddr*)&server_address,
sizeof(server_address)) < 0) {
printf("could not connect to server\n");
return 1;
}
// send
// data that will be sent to the server
const char* data_to_send = "Gangadhar Hi Shaktimaan hai";
send(sock, data_to_send, strlen(data_to_send), 0);
// receive
int n = 0;
int len = 0, maxlen = 100;

EE353: Computer Networks Page 11


char buffer[maxlen];
char* pbuffer = buffer;
// will remain open until the server terminates the connection
while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {
pbuffer += n;
maxlen -= n;
len += n;
buffer[len] = '\0';
printf("received: '%s'\n", buffer);
}
// close the socket
close(sock);
return 0;
}
=============================================================

TCPServer.c
include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/**
* TCP Uses 2 types of sockets, the connection socket and the listen socket.
* The Goal is to separate the connection phase from the data exchange phase.
* */
int main(int argc, char *argv[]) {
// port to start the server on
int SERVER_PORT = 8877;
socklen_t client_address_len;
// socket address used for the server
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// htons: host to network short: transforms a value in host byte
// ordering format to a short value in network byte ordering format
server_address.sin_port = htons(SERVER_PORT);
// htonl: host to network long: same as htons but to long
server_address.sin_addr.s_addr = htonl(INADDR_ANY);

EE353: Computer Networks Page 12


// create a TCP socket, creation returns -1 on failure
int listen_sock;
if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("could not create listen socket\n");
return 1;
}
// bind it to listen to the incoming connections on the created server
// address, will return -1 on error
if ((bind(listen_sock, (struct sockaddr *)&server_address,
sizeof(server_address))) < 0) {
printf("could not bind socket\n");
return 1;
}
int wait_size = 16; // maximum number of waiting clients, after which
// dropping begins
if (listen(listen_sock, wait_size) < 0) {
printf("could not open socket for listening\n");
return 1;
}
// socket address used to store client address
struct sockaddr_in client_address;

// run indefinitely
while (true) {
// open a new socket to transmit data per connection
int sock;
if ((sock =
accept(listen_sock, (struct sockaddr *)&client_address,
&client_address_len)) < 0) {
printf("could not open a socket to accept data\n");
return 1;
}
int n = 0;
int len = 0, maxlen = 100;
char buffer[maxlen];
char *pbuffer = buffer;
printf("client connected with ip address: %s\n",
inet_ntoa(client_address.sin_addr));
// keep running as long as the client keeps the connection open
while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {

EE353: Computer Networks Page 13


pbuffer += n;
maxlen -= n;
len += n;
printf("received: '%s'\n", buffer);
// echo received content back
send(sock, buffer, len, 0);
}
close(sock);
}
close(listen_sock);
return 0;
}
=============================================================

4.2.1 Lab Task 2: A useful Python TCP client/server application.

Modify the TCPClient program such that the TCPClient is able to calculate
the Application level Round Trip Time (RTT) for the communication
between the Client and the Server. The Client should also print the time
when connection request is send and time when the Reply (capitalized
words) is received in human readable form.
Please paste your source code for TCPClient and screen shot of the output for Lab
Task 2 here.

4.2.2 Lab Task 3: Compare the values of the RTT for both the UDP and
TCP. Which one has got higher RTT? Why?

Please type your descriptive answer for Lab Task 3 here.

4.2.3 Lab Task 4: What happens when your client (both UDP and TCP)
tries to send data to a non-existent server?
Please type your descriptive answer and screen shot of the output for Lab Task 4 here.

1.1 Unix Socket – Functions Summary(From TutorialsPoint.com)


Here is a list of all the functions related to socket programming.

EE353: Computer Networks Page 14


1.2 Port and Service Functions
Unix provides the following functions to fetch service name from the /etc/services file.
• struct servent *getservbyname(char *name, char *proto) − This call takes a
service name and a protocol name and returns the corresponding port number
for that service.
• struct servent *getservbyport(int port, char *proto) − This call takes a port
number and a protocol name and returns the corresponding service name.

1.3 Byte Ordering Functions


• unsigned short htons (unsigned short hostshort) − This function converts
16-bit (2-byte) quantities from host byte order to network byte order.
• unsigned long htonl (unsigned long hostlong) − This function converts 32-bit
(4-byte) quantities from host byte order to network byte order.
• unsigned short ntohs (unsigned short netshort) − This function converts 16-
bit (2-byte) quantities from network byte order to host byte order.
• unsigned long ntohl (unsigned long netlong) − This function converts 32-bit
quantities from network byte order to host byte order.

1.4 IP Address Functions


• int inet_aton (const char *strptr, struct in_addr *addrptr) − This function call
converts the specified string, in the Internet standard dot notation, to a network
address, and stores the address in the structure provided. The converted
address will be in Network Byte Order (bytes ordered from left to right). It returns
1 if the string is valid and 0 on error.
• in_addr_t inet_addr (const char *strptr) − This function call converts the
specified string, in the Internet standard dot notation, to an integer value suitable
for use as an Internet address. The converted address will be in Network Byte
Order (bytes ordered from left to right). It returns a 32-bit binary network byte
ordered IPv4 address and INADDR_NONE on error.
• char *inet_ntoa (struct in_addr inaddr) − This function call converts the
specified Internet host address to a string in the Internet standard dot notation.

1.5 Socket Helper Functions


• void bzero (void *s, int nbyte) − The bzero function places nbyte null bytes in
the string s. This function will be used to set all the socket structures with null
values.

EE353: Computer Networks Page 15


• int bcmp (const void *s1, const void *s2, int nbyte) − The bcmp function
compares the byte string s1 against the byte string s2. Both the strings are
assumed to be nbyte bytes long.
• void bcopy (const void *s1, void *s2, int nbyte) − The bcopy function copies
nbyte bytes from the string s1 to the string s2. Overlapping strings are handled
correctly.
• void *memset(void *s, int c, int nbyte) − The memset function is also used to
set structure variables in the same way as bzero.
Refernces

Tuturiopoint.com

https://www.csd.uoc.gr/~hy556/material/tutorials/cs556-3rd-tutorial.pdf

EE353: Computer Networks Page 16

You might also like