Click here to Skip to main content
15,867,756 members
Articles / Desktop Programming / MFC

Socket Programming with MFC (Part 1)

Rate me:
Please Sign up or sign in to vote.
4.18/5 (59 votes)
9 Nov 20054 min read 442.1K   21.2K   127   61
An article on Socket Programming with MFC
Sample Image - MFCSockets.jpg

Introduction

Socket Programming is a very interesting activity in most of the programming languages. It's a nice activity to write Servers and Clients that communicate over a network. In Windows Platform, socket communications are based on Microsoft Winsock architecture. Windows supports both stream based (TCP) and Datagram based (UDP) socket communication. Windows APIs are available for socket programming, but many find it difficult to work with them.

So here I am going to explain the easiest way to do socket programming using MFC socket classes. This will not only make your job easy, but will also reduce the development time for your network applications. You can develop a custom made socket class that you can reuse in all the network based applications that you write. I will explain these concepts by developing an Echo Server application.

The MFC Socket Classes

For Socket programming, MFC provides two built in classes named CAsyncSocket and CSocket. CSocket is inheriting its functionality from CAsyncSocket. CAsyncSocket class provides several notification functions ,that will be called automatically upon occurrence of the socket events. Moreover, it acts as the base class for the complete event driven socket communication.

We can create our own customised socket classes by inheriting from CAsyncSocket class, which will serve our application specific needs. At first socket environment needs to be initialized by calling the AfxSocketInit() function.

Initializing Sockets

To initialize sockets, we need to call the function AfxSocketInit(). It is usually called from the InitInstance() function of the MFC application. If we are using a wizard to generate the application, checking the option "use Windows Sockets" will automatically do this job for us. It returns a value to indicate success or failure of the call.

C++
BOOL CEchoServerApp::InitInstance()
{....
if( AfxSocketInit() == FALSE)
  { 
  AfxMessageBox("Sockets Could Not Be Initialized"); 
  return FALSE; 
  }
  ...
}

Creating Server Sockets

To create a Server socket, we need to declare a variable of type CAsyncSocket or our own class derived from CAsyncSocket or CSocket. Then we must call the create() function with the port to be listened as argument. It returns a value to indicate success or failure of the call:

C++
UpdateData(TRUE);
m_sListener.Create(m_port);
if(m_sListener.Listen()==FALSE) 
{ 
AfxMessageBox("Unable to Listen on that port, please try another port"); 
C++
m_sListener.Close(); 
return; 
}

Creating Client Sockets

To create a Client socket, first we need to declare a variable of type CAsyncSocket or our own class derived from CAsyncSocket or CSocket. Then we must call the create() function without any arguments. It returns a value to indicate success or failure of the call:

C++
m_sConnected.Create();
m_sConnected.Connect("server ip",port);

Listening for Incoming Connections

For making the server socket listen to the Specific port, we must call the function Listen(). It returns a value to indicate success or failure of the call:

C++
if( m_sListener.Listen()== FALSE) 
{ 
AfxMessageBox("Unable to Listen on that port, please try another port"); 
C++
m_sListener.Close(); 
return;
}

Accepting Connections

The incoming connection must be accepted to another socket (not the listening socket). It is done by calling the Accept function with the second socket as argument.

C++
void CEchoServerDlg::OnAccept()
{
 CString strIP; 
 UINT port; 
 if(m_sListener.Accept(m_sConnected)) 
 {
  m_sConnected.GetSockName(strIP,port); 
  m_status="Client Connected,IP :"+ strIP; 
  m_sConnected.Send("Connected To Server",strlen("Connected To  Server"));      
UpdateData(FALSE); 
 }
 else 
 { 
 AfxMessageBox("Cannot Accept Connection"); 
 } 
}

Sending Data

The data to be sent is kept in a buffer and a pointer to it and its length is passed to the send function:

C++
m_sConnected.Send(pBuf,iLen);

Receiving Data

Data is received by calling the function receive(buffer,maxlength):

C++
void CEchoServerDlg::OnReceive() 
{ 
char *pBuf =new char [1025]; 
CString strData; 
int iLen;
iLen=m_sConnected.Receive(pBuf,1024);    
if(iLen == SOCKET_ERROR)      
  {
  AfxMessageBox("Could not Receive");      
  }      
else     
  { 
  pBuf[iLen]=NULL;
  strData=pBuf;
  m_recieveddata.Insert(m_recieveddata.GetLength(),strData); 
 //display in server              
 UpdateData(FALSE); 
 m_sConnected.Send(pBuf,iLen);  //send the data back to the Client   
 delete pBuf;          
  } 
}

Shutting Down Connection

C++
m_sConnected.ShutDown(0);    Stops  Sending Of Data 
m_sConnected.ShutDown(1);    Stops Receiving of data
m_sConnected.ShutDown(2);    Stops Both Sending and Receiving of Data

Closing Connection

C++
m_sConnected.Close();

Socket Events

Several functions are used for notification of events. They are to be overridden by descendant classes, in the form of protected member functions.

  1. OnAccept() indicates that a connection is pending to be accepted
  2. OnClose() indicates that application at the other end has closed the socket
  3. OnConnect() indicates that Connection establishment is complete
  4. OnSend() indicates that Data is being sent
  5. OnReceive() indicates that Data is being received
  6. OnOutofBandData() indicates that out of band data (urgent message) has arrived

Deriving Our Own Socket Class from CAsyncSocket

For deriving our own socket class, go to class view and add a new class and set its base class as CAsyncSocket. With the help of classwizard, add notification functions as shown below:

C++
class MyEchoSocket : public CAsyncSocket
{ // Attributes 
public: 
 // Operations
public: 
MyEchoSocket(); 
virtual ~MyEchoSocket(); 
// Overrides 
public: 
void SetParentDlg(CDialog *pDlg);// ClassWizard generated virtual function overrides 
//{{AFX_VIRTUAL(MyEchoSocket) 
public: 
virtual void OnAccept(int nErrorCode);
virtual void OnClose(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnOutOfBandData(int nErrorCode);
virtual void OnReceive(int nErrorCode); 
virtual void OnSend(int nErrorCode); 
//}}AFX_VIRTUAL // Generated message map functions 
//{{AFX_MSG(MyEchoSocket) 
// NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG 
C++
protected: 
private:
CDialog * m_pDlg; 
};

Setting The "Parent Dialog"

The socket class's SetParentDlg function is called to ensure that notifications are received to the dialog class when socket events occur:

C++
m_sListener.SetParentDlg(this); 
m_sConnected.SetParentDlg(this);

Linking Socket Events With Dialog Class Member Functions

In the dialog class, add the appropriate functions like:

C++
void OnReceive(); 
void OnClose(); 
void OnAccept(); 
void OnConnect();

These functions are called from the socket class as shown below:

C++
void MyEchoSocket::OnAccept(int nErrorCode) 
{ 
// TODO: Add your specialized code here and/or call the base class 
if(nErrorCode==0) 
{ 
((CEchoServerDlg*)m_pDlg)->OnAccept(); 
}
CAsyncSocket::OnAccept(nErrorCode); 
} 

Using the Code

The attached project is ready to be compiled and executed. Just open with Visual C++ 6.0 and compile. It is an EchoServer that echoes back whatever data is sent to it. You can use a telnet client to connect to it. The sending and receiving functionality can be tested easily from telnet console.

History

  • Version 1.0, Part 1 of MFC Socket Programming [ 10/11/2005 ]

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
http://jobinwilson.blogspot.com/

Comments and Discussions

 
QuestionClient Source Code Pin
kktt3-Sep-17 22:01
kktt3-Sep-17 22:01 
Questiontoo good .... and simple explanation Pin
Member 863706725-Nov-16 7:37
Member 863706725-Nov-16 7:37 
QuestionSmall change suggestion : Possible memory leak Pin
Nitesh1010116-Nov-16 17:43
Nitesh1010116-Nov-16 17:43 
AnswerRe: Small change suggestion : Possible memory leak Pin
mzdude29-Jul-21 4:24
mzdude29-Jul-21 4:24 
QuestionRunning Echo Server Pin
Ivan Chemelekov9-Aug-15 16:22
Ivan Chemelekov9-Aug-15 16:22 
AnswerRe: Running Echo Server Pin
Chandy Kunhu8-May-18 0:34
Chandy Kunhu8-May-18 0:34 
QuestionConnection Time-out in Client Side Pin
Moharram28-Dec-14 19:47
Moharram28-Dec-14 19:47 
QuestionError C3861: 'AfxSocketInit': identifier not found Pin
indra30405-Nov-13 19:50
indra30405-Nov-13 19:50 
GeneralMy vote of 5 Pin
JasMineLeaf17-Oct-13 21:23
JasMineLeaf17-Oct-13 21:23 
QuestionSetParentdlg Pin
yossisw25-Aug-13 23:38
yossisw25-Aug-13 23:38 
GeneralMy vote of 5 Pin
Christian Koberg25-Jun-13 4:55
Christian Koberg25-Jun-13 4:55 
Questionthankssssss Pin
Member 999976523-May-13 8:02
Member 999976523-May-13 8:02 
GeneralMy vote of 4 Pin
iampradeepsharma26-Feb-13 19:22
iampradeepsharma26-Feb-13 19:22 
GeneralMy vote of 2 Pin
Member 92600623-Jan-13 21:41
Member 92600623-Jan-13 21:41 
GeneralMy vote of 5 Pin
nethajiprasath26-Jun-12 0:56
nethajiprasath26-Jun-12 0:56 
QuestionClient? Pin
L12345M629-Mar-11 5:49
L12345M629-Mar-11 5:49 
Questiontelnet send: only 64 characters at one time? Pin
L12345M69-Mar-11 4:14
L12345M69-Mar-11 4:14 
QuestionHow to add a timeout? Pin
L12345M68-Mar-11 3:24
L12345M68-Mar-11 3:24 
AnswerRe: How to add a timeout? Pin
L12345M614-Mar-11 4:53
L12345M614-Mar-11 4:53 
GeneralMFC project options Pin
bkelly1319-Nov-10 16:43
bkelly1319-Nov-10 16:43 
QuestionHow to communicate between TCP Client and UDP Server. Pin
Srikanth Kodimela18-Feb-10 20:25
Srikanth Kodimela18-Feb-10 20:25 
Please give me an example for TCP Client communicates with a UDP Server.
I am new to socket programming.
I have to develop an application which is TCP Socket, it should interact with UDP based Hardware.
Please give me some Idea and Example.

Advance thanks for the Reply.

Srithesh.
General[Message Deleted] Pin
it.ragester2-Apr-09 21:56
it.ragester2-Apr-09 21:56 
Questionhow to create multi client communication Pin
N.Ravi Raj1-Dec-08 18:05
N.Ravi Raj1-Dec-08 18:05 
GeneralConnecting multiple clients to one port. Pin
Tpasta2-Jul-08 5:14
Tpasta2-Jul-08 5:14 
GeneralRe: Connecting multiple clients to one port. Pin
L12345M620-Mar-11 23:50
L12345M620-Mar-11 23:50 

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.