Click here to Skip to main content
Click here to Skip to main content

Socket Programming with MFC (Part 1)

By , 9 Nov 2005
 
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.

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:

UpdateData(TRUE);
m_sListener.Create(m_port);
if(m_sListener.Listen()==FALSE) 
{ 
AfxMessageBox("Unable to Listen on that port, please try another port"); 
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:

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:

if( m_sListener.Listen()== FALSE) 
{ 
AfxMessageBox("Unable to Listen on that port, please try another port"); 
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.

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:

m_sConnected.Send(pBuf,iLen);

Receiving Data

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

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

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

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:

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 
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:

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:

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

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

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

About the Author

Jobin Wilson
Web Developer
United States United States
Member
http://jobinwilson.blogspot.com/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionthankssssssmemberMember 999976523 May '13 - 8:02 
really nice article...................... Poke tongue | ;-P
GeneralMy vote of 4memberiampradeepsharma26 Feb '13 - 19:22 
nice
GeneralMy vote of 2memberMember 92600623 Jan '13 - 21:41 
I dont like the way to programme
GeneralMy vote of 5membernethajiprasath26 Jun '12 - 0:56 
the way he explains is easy to understand....
QuestionClient?memberL12345M629 Mar '11 - 5:49 
I am trying to develop a client which connects to the Server, instead of using telnet. Any good ideas? At the moment, when I am using CSocket, the connection is refused by the server.
Questiontelnet send: only 64 characters at one time?memberL12345M69 Mar '11 - 4:14 
When I send a character string with telnet: "send xxx" only those with less than 64 characters are trasnmitted. Is it telnet or is it the programm that limits the string? Because I thought the buffer of the programm is a 1024 character array, and I read that telnet is unlimited
QuestionHow to add a timeout?memberL12345M68 Mar '11 - 3:24 
Good work, I am successfully using our code. Thank you very much for sharing it!
I am also trying to add a timeout to it: when the Server don't get an answer from the Client for one or two minutes, it should shut down the connection and wait for a new connection. As I am a very newbie to C++, I am trying since days to find some appropriate examples on the net, but I don't understand how and where to insert the code... maybe anybody here has already added a timeout to this example or knows how to do it?
Thanks in advance!
AnswerRe: How to add a timeout?memberL12345M614 Mar '11 - 4:53 
I got it: http://63.236.73.79/forum/showthread.php?p=2003395#post2003395[^]
GeneralMFC project optionsmemberbkelly1319 Nov '10 - 16:43 
Please provide a list of the options that a VS novice should select when creating the a project for this example code.
Thanks for your time

QuestionHow to communicate between TCP Client and UDP Server.memberksrithesh18 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]memberit.ragester2 Apr '09 - 21:56 
[Message Deleted]
Questionhow to create multi client communicationmemberN.Ravi Raj1 Dec '08 - 18:05 
Hai! This article is super and using this i am able to commuincate a server and a client.But i am not able to commuincate with multi client. Server is able to send messages to recently connected client.But server not able to receive messages from it. How to make the multi client communication.Pre thanks to your valuable suggestions.
GeneralConnecting multiple clients to one port.memberTpasta2 Jul '08 - 5:14 
Jobin,
 
I am having problems connecting 3 clients to one socket. How can I do this?
 
Whenever I connect again, an assertion msg gets sent. I can only get focus one one hyperterm at a time. I need all hyperterms to be active.
 
Thanks
Tony
GeneralRe: Connecting multiple clients to one port.memberL12345M620 Mar '11 - 23:50 
It's this line causing the eassertion message: if(m_sListener.Accept(m_sConnected))
There must be more than one client (m_sConnected) defined. I am working on this issue and trying to get a solution how it works with two Clients.
GeneralRe: Connecting multiple clients to one port.memberL12345M621 Mar '11 - 3:41 
I got it. Defined a third EchoSocket:
MyEchoSocket m_sClient2;
and a counter
static int nbClients;
The Code is quick and dirty, but it works (just sending and receiving I did not yet finish). On every position where m_sConnected is manipulated, I now ask how many Clients are there, and then also manipulate m_sClient2.
For example:
m_sClient2.SetParentDlg(this);
and in the function OnAccept (if nb_Clients = 0 then do first one, if =1 do the 2nd) and in the function OnButton2 for closing... and so on.
QuestionHow can i do UDP socket programmingmemberbuntyrolln5 Jun '08 - 19:30 
Hai
This example seems to be TCP socket programming.
Please help me in writing UDP socket programmng (Server Program)
 
Thanks and Regards
Suraj
 
suraj

Generalgood sourcememberAhn Jung Woo13 Sep '07 - 17:39 
good source...
 
12

GeneralSocket multi-languagememberproITer4 Sep '07 - 18:34 
I must create an application which can transfert data via socket. The client-side write by C++ (may be MFC). The Server-side write by Java or VB6. now, I had tested a lot of ways, but they can't transfert data to other, althought they were connected themself. Pre-thanks for your helps, you can list to me some solutions?Frown | :(
Questionproblem with connecting to a server.membernishchal_devnur25 Jun '07 - 0:30 
Hi,
I have two programs, one a server program and the other client. If i run the both the programs on the same machine evrything works fine. But if i run the two programs on different machines the client is not able to connect to the server and i get a error code(10060, which means connection timed out).Please suggest any solution.
 
Thank you,
 
Nishchal
QuestionUsing CAsyncSocket in a Console Application ???memberlutzTobias19 Apr '07 - 2:30 
Hi!
At first I have to say that this is a very good tutorial. Thanks!
 
But I have another question.
Is it possible to use the CAsynchSocket in a console application too?
 
If i create an VS6 project (MFC-Application Wizzard (.exe)) everything works fine.
 
But if i create a "win32 console application" project with the same code,
I receive always an error from the function socket.Listen().
There are no errors while compiling and linking.
 
Does anyone have a clue how to use the MFC CAsyncSocket in a console application?
 

Thanks!
 
Tobias

QuestionPlease explain the objective of this project...membershampyshanky24 Mar '07 - 23:22 
i m not able to understand the real motive/objective behind this project..
can u plz elaborate it?
also,plz tell the meaning of MFC.
 
hope to get quick reply frm u...
 
thnx a lot

AnswerRe: Please explain the objective of this project...memberthenotwist28 Jul '07 - 14:12 
This article was written to show you how to use the MFC Csocket/CAsyncSocket class in your applications... to me, it's easier to do stuff this way than using the API functions.
 
MFC = Microsoft Foundation Classes
Generalproblem in transfeering contextsmemberVishwas Bharadwaj7 Feb '07 - 8:15 
Smile | :) hie ppl.. am vry new to this socket programin stuff.. had a gr8 understandin of the same with the above code.. AM having a prob in transferring contexts.. as in am having an application that supports free hand drawing and i neeed to transfer the stokes captured to another same application on another comp.. am using CPoint to store the points and MoveTo and LineTo functions in implementing freehand..
awaiting a reply from u all in helping me how to go bout this...
 
with regards
 
vish
QuestionHow to test this application?memberMikeRT23 Nov '06 - 19:28 
Hi,
I know that this question is very foolish..But I am new to socket programming. Please tell how to test this application? I am not aware of what port no has to given and how to use telnet console to send data? and which telnet command to use for it?..
I hope i will get the reply soon.
 
Thanks:-
Rajiv
AnswerRe: How to test this application?memberJobin Wilson29 Nov '06 - 19:30 
Hi Rajiv,
let me explain it in a couple of steps
1.enter any number (say 3764) into the application's port number box
2.press the Listen button
3.launch the telnet appllication (go to Run from the start button,enter "telnet"
4.you will have the telnet prompt now,there type "open localhost 3764" (use the same number that u used in step1) and hit enter
5.gotcha!!! you are connected to the server now!!! Smile | :)
 
Thanks
Jobin
 

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 10 Nov 2005
Article Copyright 2005 by Jobin Wilson
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid