Click here to Skip to main content
15,444,353 members
Articles / Desktop Programming / MFC
Posted 20 Oct 2001


39 bookmarked

MC++ TCP server talking to MFC & MC++ TCP clients

Rate me:
Please Sign up or sign in to vote.
4.92/5 (34 votes)
1 Jul 2002CPOL4 min read
Basic demonstration of the TcpListener/TcpClient classes.


The original article proposed to demonstrate elementary network programming by designing a very simple SMTP server class. It had no support for sending attachments and was quite uncomplicated in nature. Since there are much better classes available within the BCL for sending emails, the exercise seemed to be quite futile. Therefore I have updated the article so that it provides a decent introduction to network programming. There are already several introductions to network programming on the web and I wanted this to be slightly different from all of them. Whether I was successful in that endeavor is up to the end-readers to judge.

Basically with the advent of .NET, remoting and web services are the preferred means of network communication. Both mechanisms are object oriented and allows the programmer to work from a high level of abstraction. But there are often situations, where you might want to communicate with native programs that were written prior to .NET, or for some reason you cannot expect all clients to be running .NET enabled programs. That's where we can use the slightly lower level network classes for our network-based programs. There is a Socket class available but I prefer to use the TcpListener and TcpClient classes which offer a higher level of abstraction.

In this article we'll design a multi-threaded TCP server using Managed C++. This server is very simple in functionality. It accepts a line of text and returns the reversed version of the same. We'll write an MFC dialog based application that will use the MFC CSocket class to chat with our Managed C++ TCP server. Since we have used basic TCP protocol, it does not matter what language the client program is written in. Just to complete the wheel, I also include a Managed C++ version of the TCP client, which also serves to demonstrate the TcpClient class.

TCP server - MC++

We write two classes here - SpookServer which basically starts our TCP server and listens for connections, and SpookClient which is a class for handling individual client connections. The SpookServer class itself spawns off a new thread in which it waits for connections. And for each connection, it instantiates a SpookClient object which immediately spawns off a new thread to handle the particular client connection. This system of one thread per client is quite acceptable in our case because each TCP chat involves so little process flow. It's just a matter of accepting a line of text, reversing it and sending it back.

The SpookServer class

__gc class SpookServer
    TcpListener* lis;
    Thread* t;
    ManualResetEvent* mre;
    SpookServer(int port)
        mre = new ManualResetEvent(true);
        lis = new TcpListener(port);
        t = new Thread(new ThreadStart(this,&SpookServer::ServerThread));
    void CloseServer()
    void ServerThread()
                TcpClient* c = lis->AcceptTcpClient();
                SpookClient* sc = new SpookClient(c);
            catch(Exception* e)

Well, the class is rather simple, but I'll still give a quick run-through of how it works. We use a ManualResetEvent object for synchronization. This is basically so that the calling class or method has a means of stopping the server anytime, in our case this is _tmain. As you can see, we spawn off a new thread where we listen for connections. This is so that we can return control to the calling class. We use the AcceptTcpClient method of the TcpListener class which returns a TcpClient object that is a reference to the connected client. Immediately we instantiate a new SpookClient object passing the returned TcpClient object to it's constructor. And we go back to AcceptTcpClient, thus allowing a seemingly innumerable number of clients to be able to connect at any one time.

The SpookClient class

__gc class SpookClient
    TcpClient* m_c;
    Thread* t;
    SpookClient(TcpClient* c)
        m_c = c;
        t = new Thread(new ThreadStart(this,&SpookClient::StartChat));
        t->IsBackground = true;
    void StartChat()
        NetworkStream* ns = m_c->GetStream();
        unsigned char buffer __gc[] = new unsigned char __gc[128];
        String* str = "";
            int d = ns->Read(buffer,0,127);
            str = String::Concat(str,Encoding::ASCII->GetString(buffer,0,d));
            if(str->LastIndexOf('\n') != -1)

        str = str->Trim();
        str = String::Concat("\n",str);     
        buffer = Encoding::ASCII->GetBytes(str);

The SpookClient class has a TcpClient member and we assign the TcpClient object passed to the constructor to this member object. And we start off a new thread. Inside the thread, we first call TcpClient.GetStream to get the underlying NetworkStream object. Once we have the NetworkStream object we can use Write and Read on it to send and receive data, respectively. We simply accept a line of text, by looping till a \n is encountered and then we reverse it and send it back. Remember to Flush and Close the NetworkStream object and then call Close on the

object as well.

TCP client - MFC

void CTcpClientMFCDlg::OnBnClickedButton1()
    m_text += "\n";
    CSocket s;
        m_text = "";
        char buff[17];
        int i;
        while(m_text.Find('\n') == -1)
            m_text += buff;         

Well, we don't do anything spectacular here. We simply send the text using CSocket::Send() and receive back the reversed line of text using CSocket::Receive. You'd think that with using network streams and all, the data would have been slightly personalized for .NET purposes, but apparently the raw data is preserved. This indicates that you can use the

and TcpClient classes for any kind of Tcp programming including popular protocols like HTTP, SMTP, POP3 etc.

TCP client - MC++

__gc class SpookClient
    String* Reverse(String* s)
        TcpClient* tl = new TcpClient("",20248);
        NetworkStream* nw = tl->GetStream();
        unsigned char buffer __gc[] = new unsigned char __gc[128];
        buffer = Encoding::ASCII->GetBytes(s);
        unsigned char retbuffer __gc[] = new unsigned char __gc[128];
        String* str = "";
            int d = nw->Read(retbuffer,0,127);
            str = String::Concat(str,Encoding::ASCII->GetString(retbuffer,0,d));
            if(str->LastIndexOf('\n') != -1)
        return str;

I have written another class here called SpookClient, not to be confused with the other class in the server program that has the same name. This uses a TcpClient object to connect to the server, gets the underlying NetworkStream using GetStream and uses Write and Read for sending and receiving data, to and from the server. This code snippet would look very similar to our client handler class in the server program because they both demonstrate the use of the



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

Written By
United States United States
Nish Nishant is a Principal Software Architect based out of Columbus, Ohio. He has over 17 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish was a Microsoft Visual C++ MVP between 2002 and 2015.

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored C++/CLI in Action for Manning Publications in 2005, and had previously co-authored Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on and another 250+ blog articles on his WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : If you are interested in hiring Nish as a consultant, you can reach him via his google email id voidnish.

Company Website :

Comments and Discussions

GeneralCode Converted From /clr:oldSyntax to /Clr Pin
Nathan Sharp10-Feb-07 12:44
MemberNathan Sharp10-Feb-07 12:44 
GeneralCSocket Receive Pin
fahad_iub17-Nov-04 0:09
Memberfahad_iub17-Nov-04 0:09 
GeneralRe: CSocket Receive Pin
Anonymous20-Sep-05 2:08
MemberAnonymous20-Sep-05 2:08 
GeneralPOP3 Server Pin
do van sung7-Nov-04 3:27
Memberdo van sung7-Nov-04 3:27 
QuestionHow about creating a Java Client Pin
SeanV22-Jul-03 8:04
MemberSeanV22-Jul-03 8:04 
AnswerRe: How about creating a Java Client Pin
Nish Nishant22-Jul-03 8:20
sitebuilderNish Nishant22-Jul-03 8:20 
GeneralC++/MFC Pin
Sid Kraft27-Jul-02 9:32
MemberSid Kraft27-Jul-02 9:32 
GeneralThanks! Pin
Matt Newman2-Jul-02 5:57
MemberMatt Newman2-Jul-02 5:57 
GeneralRe: Thanks! Pin
Nish Nishant2-Jul-02 6:41
sitebuilderNish Nishant2-Jul-02 6:41 
Matt Newman wrote:
Awesome article!

Thanks Matt! You really do read all new articles, don't you! And I also remember you saying that you have VC++ .NET standard!


Author of the romantic comedy

Summer Love and Some more Cricket [New Win]

Review by Shog9
Click here for review[NW]

GeneralRe: Thanks! Pin
Matt Newman2-Jul-02 11:17
MemberMatt Newman2-Jul-02 11:17 
GeneralNo error checking.... Pin
Anders Molin1-Nov-01 0:31
professionalAnders Molin1-Nov-01 0:31 
GeneralRe: No error checking.... Pin
Nish Nishant1-Nov-01 0:43
sitebuilderNish Nishant1-Nov-01 0:43 
GeneralRe: No error checking.... Pin
Anders Molin1-Nov-01 0:50
professionalAnders Molin1-Nov-01 0:50 
GeneralRe: No error checking.... Pin
Nish Nishant1-Nov-01 0:56
sitebuilderNish Nishant1-Nov-01 0:56 
GeneralRe: No error checking.... Pin
Rickard Andersson2012-Jun-02 4:48
MemberRickard Andersson2012-Jun-02 4:48 
GeneralRe: No error checking.... Pin
Anders Molin12-Jun-02 8:44
professionalAnders Molin12-Jun-02 8:44 
GeneralI used something similiar Pin
28-Nov-01 12:12
suss28-Nov-01 12:12 

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.