Sunday, April 18, 2010

My own chat application in C!!!!

After an standing-out(not outstanding :P) performance in GATE 2010 and missing the prestigious 99th percentile with just one question, I have to console myself for my shattered dream of being an IITian. I am looking for Tier-2 colleges now(I call IITs as tier-1 and NITs and IIITs as tier-2). I got an interview call from IIIT-B to be held on May 5th. In their interview a candidate has to present a technical talk of 5-10 minutes on any technical topic of his/her choice. He/She is then fired questions from the same topic by the selection committee. I have decided to speak on the topic "SOCKET COMMUNICATION". While the preparation I thought I should have an inside view of how it works by developing an application using it. After lots of research on the internet and many trial and errors I finally coded this crude chat application in C. You may also use it in your assignment if you're a student in search for stuff to do your assignments.

Note:
When one user is typing the message, the second one should not write anything :P i.e. it works similar to a walkie talkie.


Usage:
1. Compile the code into an object file and link the object file with wsock32.lib to generate the executable. I designed it and compiled it with Digital Mars Compiler & Linker You may use any compiler but you may need to modify the code a bit, based on your compiler.

To compile and link on dmc(that stands for Digital Mars Compiler) use these commands:
dmc -c chat.c
dmc chat.o wsock32.lib

2. You can test this app on two PCs/Laptops on LAN/WLAN. Launch it through command line on one computer. On the second launch it with the ip address of first computer as the command line argument.
For example(assuming it is placed in D:\'s root with the name chat.exe)
On first computer:
1. Window Key+R
2. Type cmd and press enter
3. Type d:\chat and press enter

On second computer:
1. Window Key+R
2. Type cmd and press enter
3. Type d:\chat <ip_of_first_comp.> like d:\chat 192.168.0.1



Download the executable here

Here is the source code:


#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>

#define MAXPENDING 1 /* Maximum outstanding connection requests */

void DieWithError(char *errorMessage); /* Error handling function */

void main(int argc, char *argv[])
{
short runtype; /* 0 for client, 1 for server*/
int serv_sock; /* Socket descriptor for server */
int clnt_sock; /* Socket descriptor for client */
struct sockaddr_in serv_addr; /* Server address */
struct sockaddr_in clnt_addr; /* Client address */
unsigned short port=9797; /* Port for communication */
unsigned int clnt_len; /* Length of client address data structure */
char msg[1024]; /* For chat message */
int msg_len;
int bytes; /* Byte count for received data */
WSADATA wsaData; /* Structure for WinSock setup communication */


switch(argc){
case 1:
runtype=0;
break;
case 2:
runtype=1;
break;
default:
printf("Invalid use of application. Usage: %s [<ip_addr>]",argv[0]);
exit(1);
break;
}

if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
{
fprintf(stderr, "WSAStartup() failed");
exit(1);
}


if (runtype==0){
/* Create socket for incoming connections */
if ((serv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");

/* Construct local address structure */
memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */
serv_addr.sin_family = AF_INET; /* Internet address family */
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
serv_addr.sin_port = htons(port); /* Port */

/* Bind to the local address */
if (bind(serv_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
DieWithError("bind() failed");

/* Mark the socket so it will listen for incoming connections */
if (listen(serv_sock, MAXPENDING) < 0)
DieWithError("listen() failed");

/* Set the size of the in-out parameter */
clnt_len = sizeof(clnt_addr);
/* Wait for a client to connect */
printf("Waiting for a user to connect...\n");
if ((clnt_sock = accept(serv_sock, (struct sockaddr *) &clnt_addr, (int *)&clnt_len)) < 0)
DieWithError("accept() failed");
printf("Connected to %s. Type message and press enter to send. Ctrl+C to terminate.\n\n", inet_ntoa(clnt_addr.sin_addr));
while(1){
/* Receive message from client */
if ((bytes = recv(clnt_sock, msg, 1024, 0)) < 0)
DieWithError("recv() failed");
/*Put a null terminator at the last byte*/
msg[bytes]='\0';
printf("%s says: %s\n",inet_ntoa(clnt_addr.sin_addr),msg);
printf("You say: ");
gets(msg);
msg_len=strlen(msg);
if (send(clnt_sock, msg, msg_len, 0) != msg_len)
DieWithError("send() failed");
}
}
else if(runtype==1){
char *serv_ip;
serv_ip=argv[1];
/* Create a reliable, stream socket using TCP */
if ((clnt_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */
serv_addr.sin_family = AF_INET; /* Internet address family */
serv_addr.sin_addr.s_addr = inet_addr(serv_ip); /* Server IP address */
serv_addr.sin_port = htons(port); /* Server port */
/* Establish the connection to the chat server */
if (connect(clnt_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
DieWithError("connect() failed");
printf("Connected to %s. Type your message and press enter to send. Ctrl+C to terminate.\n\n",argv[1]);

while(1){
printf("You say: ");
gets(msg);
msg_len = strlen(msg); /* Determine input length */
/* Send the string, including the null terminator, to the server */
if (send(clnt_sock, msg, msg_len, 0) != msg_len)
DieWithError("send() sent a different number of bytes than expected");
if ((bytes = recv(clnt_sock, msg, 1024, 0)) <= 0)
DieWithError("recv() failed or connection closed prematurely");
msg[bytes]='\0';
printf("%s says: %s\n", argv[1], msg); /* Print the message */
}
}
}
void DieWithError(char *errorMessage)
{
fprintf(stderr,"%s: %d\n", errorMessage, WSAGetLastError());
exit(1);
}

5 comments:

REY said...

Mast hai.. xD

prab97 said...

:grin

Unknown said...

ladka mast genious hai :))))))

Unknown said...

would you like to send me some explain for this chat code please..
send me febriyana.es.en@gmail.com

thanks

for ict 99 said...
This comment has been removed by a blog administrator.