Professional Documents
Culture Documents
on
of
BACHELOR OF TECHNOLOGY
In
I hereby declare that the project entitled “Chat application using UDP socket programming”
submitted as part of the partial course requirements for the course Computer Networks, for the award
University Jaipur during the 6th Semester, April, 2019 , has been carried out by me. I declare that the
project has not formed the basis for the award of any degree, associate ship, fellowship or any other
Further, I declare that I will not share, re-submit or publish the code, idea, framework and/or
any publication that may arise out of this work for academic or profit purposes without obtaining the
prior written consent of the Course Faculty Mentor and Course Instructor.
Place:
Date:
Page 2 of 20
ACKNOWLEDGEMENT
If words are considered as a symbol of approval and token of appreciation then let the words
play the heralding role expressing my gratitude. The satisfaction that accompanies that the
successful completion of any task would be incomplete without the mention of people whose
ceaseless cooperation made it possible, whose constant guidance and encouragement crown all
efforts with success. We are grateful to our project guide Dr. Anshuman Kalla for the guidance,
inspiration and constructive suggestions that helpful us in the preparation of this project. We also
thank our colleagues who have helped in successful completion of the project.
Page 3 of 20
Table of Contents
2. Declaration 2
3. Acknowledgement 3
4. Introduction 4
5. Software Architecture 6
6. Contribution 8
7. System Specification 9
8. Work Done 10
Page 4 of 20
Introduction
Page 5 of 20
Software Architecture
Socket Overview
A socket is an object that represents a low level access point to the IP stack. This socket can be
opened or closed or one of a set number of intermediate states. A socket can send and receive
data down disconnection. Data is generally sent in blocks of few kilobytes at a time for
efficiency; each of these block are called a packet. All packets that travel on the internet must use
the Internet Protocol. This means that the source IP address, destination address must be included
in the packet. Most packets also contain a port number. A port is simply a number between 1 and
65,535 that is used to differentiate higher protocols. Ports are important when it comes to
programming your own network applications because no two applications can use the same port.
Packets that contain port numbers come in two flavors: UDP and TCP/IP. UDP has lower latency
than TCP/IP, especially on startup. Where data integrity is not of the utmost concerned, UDP can
prove easier to use than TCP, but it should never be used where data integrity is more important
than performance; however, data sent by UDP can sometimes arrive in the wrong order and be
effectively useless to the receiver. TCP/IP is more complex than UDP and has generally longer
latencies, but it does guarantee that data does not become corrupted when travelling over the
internet. TCP is ideal for file transfer, where a corrupt file is more unacceptable than a slow
download; however, it is unsuited to internet radio, where the odd sound out of place is more
acceptable than long gaps of silence.
UDP Ports
The User Datagram Protocol is an unreliable, connectionless oriented protocol that uses an IP
address for the destination host and a port number to identify the destination application.
The UDP port number is distinct from any physical port on a computer such as a COM port or an
I/O port address. The UDP port is a 16-bit address that exists only for the purpose of passing
certain types of datagram information to the correct location above the transport layer of the
protocol stack.
Page 6 of 20
A UDP datagram header consists of four (4) fields of two bytes each:
3. datagram size
4. checksum
End point is a combination of IP address and port number. Endpoint objects allow you to easily
establish and communicate over TCP/IP network connections between client and server
processes, possibly residing on different hosts. The Endpoint class follows a telephone-like
model of networking: clients "call" servers and servers "answer" clients. Once a network
connection is established between a client and a server, the two can "talk" to each other by
reading from and writing to the connection.
The Software Process Model used is the Spiral Model. The choice for this model is in the light of
the enhancements that we foresee for the future. The enhancements would be in the area of
Networks being introduced into the software.
Conclusion
This chapter has given a broad picture of the design of the software in terms of the different
modules used. It also gives us an idea about the degree to which each module performs related
tasks. We also get an idea about the interdependence among the modules.
Page 7 of 20
Contribution to the Project
A project is successfully completed only when there is contribution of all the members of a team.
Each member in the project has a required objective to accomplish .In same way to complete this
project we divided our work in equal manner. Instead of selecting a particular task to do
individually, we divided a single task in multiple subtasks so that we all can work together on the
same phase or task of the project. Doing so no team member had to wait to show his or her
capabilities.
Page 8 of 20
SYSTEM SPECIFICATION
Hardware requirements
In hardware requirement we require all those components which will provide us the platform for the
development of the project. The minimum hardware required for the development of this project is as
follows— Ram- minimum 128 MB Hard disk—minimum 5 GB Processor- Pentium 3 Floppy drive 1.44”
inch CD drive These all are the minimum hardware requirement required for our project. We want to
make our project to be used in any. Type of computer therefore we have taken minimum configuration
to a large extent.128 MB ram is used so that we can execute our project in a least possible RAM.5 GB
hard disk is used because project takes less space to be executed or stored. Therefore minimum hard
disk is used. Others enhancements are according to the needs. 3.2 Software requirements Software’s
can be defined as programs which run on our computer .it act as petrol in the vehicle. It provides the
relationship between the human and a computer. It is very important to run software to function the
computer. Various software’s are needed in this project for its development. Which are as follows—?
Operating system—Windows 7 Others—Visual Studio We will be using visual basic as our front hand
because it is easier to use and provides features to the users which is used for the development of the
project.
Page 9 of 20
Source Code
Server Code
/* server */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "chat.h"
int sockfd;
client clientList;
char requestBuffer[BUF_SIZE];
char responseBuffer[BUF_SIZE + USERNAME_LEN];
char sender_name[USERNAME_LEN];
void userColor(int n) {
strcat(responseBuffer, colors[(n % NCOLORS)]);
}
/* function returns true if the two passes internet address are identical */
Page 10 of 20
int clientCompare(struct sockaddr_in client1, struct sockaddr_in client2) {
if(strncmp
((char *) &client1.sin_addr.s_addr, (char *) &client2.sin_addr.s_addr,
sizeof(unsigned long)) == 0) {
if(strncmp((char *) &client1.sin_port, (char *) &client2.sin_port, sizeof(unsigned short))
== 0) {
if(strncmp
((char *) &client1.sin_family, (char *) &client2.sin_family,
sizeof(unsigned short)) == 0) {
return TRUE;
}
}
}
return FALSE;
}
while(cli != NULL) {
//if sender isn't the client send out the message // may need separate clientCompare function
// use username for comparisons so noone can connect with the same username
if(clientCompare(sender, cli->address) == FALSE || global) {
printf("Sending message to %s\n", cli->username);
if((sendto
(sockfd, responseBuffer, strlen(responseBuffer), 0,
(struct sockaddr *) &cli->address, sizeof(struct sockaddr))) == SYSERR) {
perror("sendto");
close(sockfd);
exit(EXIT_FAILURE);
}
}
cli = cli->next;
}
}
while(element != NULL) {
if(clientCompare(element->address, newClient)) {
Page 11 of 20
strncpy(sender_name, element->username, USERNAME_LEN);
printf("Client is already connected\n");
return TRUE;
}
element = element->next;
}
printf("Client is not already connected\n");
return FALSE;
}
/* Used to add new clients dynamically to our server's client linked list */
/* connects a client to the server */
int connectClient(struct sockaddr_in newClient, char *username) {
printf("Attempting to connect client: %s\n", username);
client *element = &clientList;
while(element != NULL) {
if(strcmp(element->username, username) == 0) {
printf("Cannot connect client user already exists\n");
strcpy(responseBuffer, "");
strcat(responseBuffer, ERROR);
if((sendto
(sockfd, responseBuffer, strlen(responseBuffer), 0, (struct sockaddr *) &newClient,
sizeof(struct sockaddr))) == SYSERR) {
perror("sendto");
close(sockfd);
exit(EXIT_FAILURE);
}
return SYSERR;
}
element = element->next;
}
element = &clientList;
while(element->next != NULL) {
element = element->next;
}
element->next = malloc(sizeof(client));
element = element->next;
element->address = newClient;
strncpy(element->username, username, USERNAME_LEN);
element->next = NULL;
printf("Client connected\n");
return OK;
}
Page 12 of 20
/* Used to remove clients dynamically from our server's client linked list */
/* disconnects a client from the server */
int disconnectClient(struct sockaddr_in oldClient) {
printf("Attempting to disconnect client\n");
client *temp;
client *element = &clientList;
while(element->next != NULL) {
if(clientCompare(oldClient, element->next->address)) {
temp = element->next->next;
free(element->next);
element->next = temp;
printf("Client disconnected\n");
return OK;
}
element = element->next;
}
while(cli != NULL) {
printf("Client %d\n", count);
printf("%s\n", cli->username);
printf("ip: %s\n", inet_ntoa(cli->address.sin_addr));
printf("port: %d\n\n", ntohs(cli->address.sin_port));
cli = cli->next;
count++;
}
}
while(cli != NULL) {
if(clientCompare(sender, cli->address) == FALSE) {
strcpy(responseBuffer, "");
userColor(cli->address.sin_port);
strcat(responseBuffer, cli->username);
Page 13 of 20
strcat(responseBuffer, RESET "\n");
if((sendto
(sockfd, responseBuffer, strlen(responseBuffer), 0, (struct sockaddr *) &sender,
sizeof(struct sockaddr))) == SYSERR) {
perror("sendto");
close(sockfd);
exit(EXIT_FAILURE);
}
}
cli = cli->next;
}
}
//note sockaddr_in is the same size as sockaddr and can be cast to (struct sockaddr *)
bzero(requestBuffer, BUF_SIZE);
bzero(responseBuffer, BUF_SIZE + USERNAME_LEN); //zero out buffers
if(argc != 2) {
fprintf(stderr, "Usage: %s portnum\n", argv[0]);
exit(EXIT_FAILURE);
}
server_port = atoi(argv[1]); //server_port now holds the user inputed port number
//SOCK_DGRAM are datagram or connectionless sockets they use UDP and will not
nessecarily arrive in order or arrive at all
sockfd = socket(AF_INET, SOCK_DGRAM, 0); //returns socket file descriptor that can use
send() and recv() for data transmission
// last argumant protocol number given 0 will derive to protocol based on the 2nd argument
type passed
Page 14 of 20
}
/*
* LISTEN FOR PACKETS
*/
if((nbytes =
recvfrom(sockfd, requestBuffer, BUF_SIZE - 1, 0, (struct sockaddr *) &sender_addr,
(unsigned int *) &address_size)) == SYSERR) {
perror("recvfrom");
close(sockfd);
exit(EXIT_FAILURE);
}
if(isConnected(sender_addr)) {
userColor(sender_addr.sin_port);
strcat(responseBuffer, sender_name);
if(strcmp(CLOSE, requestBuffer) == 0) {
if(disconnectClient(sender_addr) == OK) { //upon success of disconnect broadcast
message to clients that user left
Page 15 of 20
}
printClientList();
}
else if(strcmp(EXIT, requestBuffer) == 0) {
strcat(responseBuffer, RED " shutdown the server" RESET "\n");
broadcast(sender_addr, TRUE);
printf("Exiting Server\n");
close(sockfd);
exit(OK);
}
else if(strcmp(LIST, requestBuffer) == 0) {
sendClientList(sender_addr);
}
else {
strcat(responseBuffer, RESET);
strcat(responseBuffer, USERNAMExMESSAGE); //inserts string between
username and message to look nice
strcat(responseBuffer, requestBuffer);
printf("Message:\n[%s]\n", responseBuffer);
//go through entire linked list and echo back the message to all clients connected with
proper username of the sender
broadcast(sender_addr, FALSE); //sends message to all except sender
}
}
else {
close(sockfd);
return OK;
}
Page 16 of 20
Client Code
/* client */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "chat.h"
int done = FALSE; //boolean that tells threads when client program is finished
void *sender(); // thread function that will take user input and send out messages to
server
void *receiver(); // thread function that will listen for received messages coming from
the server
char sendBuffer[BUF_SIZE];
char receiveBuffer[BUF_SIZE + USERNAME_LEN + 2];
int portnum;
char username[USERNAME_LEN];
if(argc != 4) {
fprintf(stderr, "Usage: %s [server] [portnum] [username]\n", argv[0]);
exit(EXIT_FAILURE);
}
Page 17 of 20
portnum = atoi(argv[2]);
strncpy(username, argv[3], USERNAME_LEN);
struct sockaddr_in server_addr; // server's internet address used for all sends and receives
//Make connection to server socket so we can use send() and recv() to read and write the
server
if(connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) == SYSERR) {
close(sockfd);
fprintf(stderr, "Failed to connect to remote server!\n");
exit(EXIT_FAILURE);
}
// Create and send out open message to the server so it knows our username and we are
identified as a connected client
strcpy(sendBuffer, username);
Page 18 of 20
if(send(sockfd, sendBuffer, strlen(sendBuffer), 0) == SYSERR) {
perror("send");
close(sockfd);
exit(EXIT_FAILURE);
}
//create threads
//Thread 1: takes in user input and sends out messages
//Thread 2: listens for messages that are comming in from the server and prints them to screen
// Set up threads
pthread_t threads[2];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
close(sockfd);
return OK;
}
void *sender() {
while(1) {
bzero(sendBuffer, BUF_SIZE);
fgets(sendBuffer, BUF_SIZE, stdin);
Page 19 of 20
pthread_mutex_unlock(&mutexsum);
}
}
void *receiver() {
int nbytes;
while(1) {
bzero(receiveBuffer, BUF_SIZE);
receiveBuffer[nbytes] = '\0';
if(strcmp(ERROR, receiveBuffer) == 0) {
printf("Error: The username %s is already taken.\n", sendBuffer);
done = TRUE;
pthread_mutex_destroy(&mutexsum);
pthread_exit(NULL);
}
else {
printf("%s", receiveBuffer);
pthread_mutex_unlock(&mutexsum);
}
}
}
Page 20 of 20