Click here to Skip to main content
15,880,956 members
Articles / Programming Languages / C++

Chatting using CSocket

Rate me:
Please Sign up or sign in to vote.
4.81/5 (28 votes)
16 Dec 2011CPOL4 min read 86.9K   10.5K   73   15
This is a simple application to demonstrate about socket, socket types, and general flow diagram of socket communication, CSocket, CAsyncSocket and its API call in the easiest manner.

Introduction

This article explains the nature and purpose of Windows Sockets. This is a simple application to demonstrate about socket, socket types, and general flow diagram of socket communication, CSocket, CAsyncSocket and its API call in the easiest manner.

Definition of a Socket

A socket is a communication endpoint — an object through which a Windows Sockets application sends or receives packets of data across a network. A socket has a type and is associated with a running process, and it may have a name. Currently, sockets generally exchange data only with other sockets in the same “communication domain,” which uses the Internet Protocol Suite.

Both kinds of sockets are bi-directional: they are data flows that can be communicated in both directions simultaneously (full-duplex).

Two socket types are available:

Stream Sockets

Stream sockets provide for a data flow without record boundaries — a stream of bytes. Streams are guaranteed to be delivered and to be correctly sequenced and unduplicated.

Datagram Sockets

Datagram sockets support a record-oriented data flow that is not guaranteed to be delivered and may not be sequenced as sent or unduplicated.

“Sequenced” means that packets are delivered in the order sent. “Unduplicated” means that you get a particular packet only once.

About CSocket

Class CSocket derives from CAsyncSocket and inherits its encapsulation of the Windows Sockets API. A CSocket object represents a higher level of abstraction of the Windows Sockets API than that of a CAsyncSocket object. CAsyncSocket operates in nonblocking mode.

Socket Flow Diagram for Client and Server Application

Chatting_using_CSocket1.JPG

Initializing Sockets

First, we need to initialize a socket using a function AfxSocketInit(), before the socket has been created. Its returns value is nonzero if the function is successful; otherwise 0.

C++
BOOL CChatServerDlg::OnInitDialog()
{
	if( AfxSocketInit() == FALSE)
	{
		AfxMessageBox("Failed to Initialize Sockets");
		return FALSE;
	}
}

Server performs the following actions. They are:

  • Create
  • Listen
  • Accept
  • Send/Receive
  • Shutdown
  • Close

Creating Server Socket

Using ServerSocket class (which is derived from CSocket) variable m_Server, a socket is created with default Port ID “1001” using create() function.

Syntax

C++
BOOL Create( UINT nSocketPort = 0, int nSocketType = SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT |
FD_CLOSE, LPCTSTR lpszSocketAddress = NULL );

For Example

C++
m_Server.create(1001);

Listening Socket

After creating the socket, we need to make the server listen to the specific port using the listen() function.

Syntax

C++
BOOL Listen( int nConnectionBacklog = 5 );

For Example

C++
m_Server.Listen( );

Accepting Client Connection Request

Client connection request is accepted by server using the accept() function call.

Syntax

C++
virtual BOOL Accept( CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr =   NULL, int* lpSockAddrLen = NULL );

For Example

C++
Accept(m_Client);

Receive Data

Call this member function to receive data from a socket. This function is used for connected sockets and is used to read incoming data.

Syntax

C++
virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 );

For Example

C++
Receive(buff,sizeof(buff));

Sending Data

Call this member function to send data on a connected socket. Send is used to write outgoing data on connected sockets.

Syntax

C++
virtual int Send( const void* lpBuf, int nBufLen, int nFlags = 0 );

For Example

C++
m_Server.m_Client.Send(buff,sizeof(userinfo));

Shutting Down Connection

Call this member function to disable sends and/or receives on the socket. ShutDown is used on all types of sockets to disable reception, transmission, or both.

Syntax

C++
BOOL ShutDown( int nHow = sends );

For Example

C++
m_Server.m_Client.ShutDown(0);	// Stop sending data.
m_Server.m_Client.ShutDown(1);	// Stop receiving data.
m_Server.m_Client.ShutDown(2);	// Stop both sending and receiving data.

Closing Connection

This function closes the socket.

Syntax

C++
virtual void Close( );

For Example

C++
m_Server.Close();

Client performs the following actions:

They are:

  • Create
  • Connect
  • Send/Receive
  • Shutdown
  • Close

The same set of syntax is used for calling functions like create(), send(), receive(), shutdown() and close().

Connecting to a Server

Call this member function to establish a connection to an unconnected socket.

Syntax

C++
BOOL Connect( LPCTSTR lpszHostAddress, UINT nHostPort );

For Example

C++
m_Client.Connect(m_sIPAddress,1001)

About the Application

Server-Side

Start Server Button

When user presses “Start Server” button that time, create() function is called to create socket with a default port id (1001) and made server to listen() to 1001 port.

Chatting_using_CSocket2.JPG

C++
void CChatServerDlg::OnStart()
{
	m_Server.m_Client.pDlg=this;

	if(m_Server.Create(1001)==FALSE)
	{
		MessageBox("Failed to create");
		return;
	}
	if(m_Server.Listen()==FALSE)
	{
		MessageBox("Failed");
		return;
	}
}

Stop Server Button

It is used to disable send and receive on the socket by calling shutdown() function and close the socket with the help of close() function.

Chatting_using_CSocket3.JPG

C++
void CChatServerDlg::OnStop()
{
	m_Server.m_Client.ShutDown(2);
	m_Server.Close();
}

Send Button

Send button is used to send data on a connected socket by calling Send() function.

Chatting_using_CSocket4.JPG

C++
void CChatServerDlg::OnSendInfo()
{
	UpdateData(TRUE);
	userinfo uinf;

	strcpy(uinf.cUserName,"Server");
	strcpy(uinf.csMsg,m_Msg);

	char *buff=(char*)&uinf;
	m_Server.m_Client.Send(buff,sizeof(userinfo));
}

For better understanding, I created two classes and they are ServerSocket.cpp and ClientSocket.cpp. Both are derived from CSocket.

When client sends the request on the socket that time Accept callback function is triggered automatically to accept client request. For understanding, I created the ServerSocket class and Accept API function is placed here.

C++
void CServerSocket::OnAccept(int nErrorCode)
{
	m_Client.m_hSocket = INVALID_SOCKET;
	AfxMessageBox("Client Request Connection");
	Accept(m_Client);	// CClinetSocket variable "m_Client" is passed.

	CSocket::OnAccept(nErrorCode);
}

ClientSocket class is created to understand that data are received from client. So Receive API function definition is done in the ClientSocket class.

C++
void CClientSocket::OnReceive(int nErrorCode)
{
	char buff[1000];

	int ibuf = Receive(buff,1000);
	buff[ibuf] = '\0';

	userinfo *udata;
	udata = (userinfo*)buff;

	((CChatServerDlg*)pDlg)->AddMsg(udata);

	CSocket::OnReceive(nErrorCode);
}

Client-Side

Connect Server Button

IP address is a must to connect with the server. So before pressing “Connect Server” button, provide IP address in the IP address text box and that address is passed to connect() function as a parameter.

Chatting_using_CSocket5.JPG
C++
void CChatClientDlg::OnConnect()
{
	UpdateData(TRUE);
	if(m_Client.Create()==FALSE)
	{
		MessageBox("Failed to Create Socket");
		return;
	}
	if(m_Client.Connect(m_sIPAddress,1001)==FALSE)// IP Address 
						//"192.168.3.30" is passed.
	{
		MessageBox("Failed to Connect");
		return;
	}
	m_Client.pDlg = this;
}

Stop Button

The same functionality is implemented for disabling send and receive and closing socket and which is cited above.

Chatting_using_CSocket6.JPG

C++
void CChatClientDlg::OnStop()
{
	m_Client.ShutDown(2);		// Disabling Send and Receive.
	m_Client.Close();
}

Send Message Button

Give user name and type message which you are going to send and user name is optional.

Chatting_using_CSocket7.JPG

Procedure to Run an Application

  1. Run “ChatSever.exe”.
  2. Press Start Server button to create a socket.
  3. Then Run “ChatClient.exe”.
  4. Give valid IP Address and press Connect Server button to establish a connection to an unconnected socket.
  5. Now server and client are ready to chat and sample snapshot given is below:

Chatting_using_CSocket8.JPG

Chatting_using_CSocket9.JPG

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
I am working in R&D department. In programming, I'm very much interested in OOPS concepts and I have written a book on "Programming in C++". My hobbies are playing cricket, painting and I have started a Educational trust "Illuminate Educational Trust".

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA18-Dec-11 3:39
professionalȘtefan-Mihai MOGA18-Dec-11 3:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.