Click here to Skip to main content
15,898,588 members
Articles / Desktop Programming / MFC
Article

Network Development Kit 2.0

Rate me:
Please Sign up or sign in to vote.
4.88/5 (114 votes)
29 Dec 2006CPOL 2.9M   25.7K   496   601
Network Development Kit is a set of simple classes for a client-server architecture.

NDK Standard

NDK in an Extension DLL

Introduction

With the success of NDK 1.0, I decided to improve the functionality. NDK represents Network Development Kit. The NDK is a set of classes that implements a client/server architecture. The NDK hides all the complexity of the connection, sending, and receiving of data over a network. You only have to deal with three classes: CNDKServer, CNDKClient, and CNDKMessage. With just a few methods to override, you obtain a complete robust client/server application. The NDK is based on the class CSocket from MFC, so you can run your application on a local network or on the Internet without any change. To easily understand the integration of the NDK in an application, you'll find at the end of this article a complete chat application.

Classes

CNDKServer: Server side of the client/server architecture

Attributes:

  • BOOL IsStarted() const;
  • long GetPort() const;
  • long GetNbUsers() const;
  • void GetUserIds(CLongArray& alIds) const;

Operations:

  • BOOL StartListening(long lPort);
  • void Stop();
  • BOOL SendMessageToUser(long lUserId, CNDKMessage& message);
  • BOOL SendMessageToAllUsers(CNDKMessage& message);
  • BOOL SendMessageToSomeUsers(const CLongArray& alUserIds, CNDKMessage& message);
  • BOOL SendMessageToAllUsersExceptFor(long lUserId, CNDKMessage& message);
  • BOOL SendMessageToAllUsersExceptFor(const CLongArray& alUserIds, CNDKMessage& message);
  • BOOL DisconnectUser(long lUserId);
  • void DisconnectAllUsers();
  • BOOL PingUser(long lUserId);
  • void PingAllUsers();

Callbacks:

  • virtual BOOL OnIsConnectionAccepted() = 0;
  • virtual void OnConnect(long lUserId) = 0;
  • virtual void OnMessage(long lUserId, CNDKMessage& message) = 0;
  • virtual void OnDisconnect(long lUserId, NDKServerDisconnection disconnectionType) = 0;
  • virtual void OnPing(long lUserId, long lNbMilliseconds);

CNDKClient: Client side of the client/server architecture

Attributes:

  • BOOL IsConnected() const;
  • BOOL GetIpAndPort(CString& strIp, long& lPort) const;

Operations:

  • BOOL OpenConnection(const CString& strServerIp, long lPort);
  • void CloseConnection();
  • BOOL SendMessageToServer(CNDKMessage& message);
  • BOOL PingServer();

Callbacks:

  • virtual void OnMessage(CNDKMessage& message) = 0;
  • virtual void OnDisconnect(NDKClientDisconnection disconnectionType) = 0;
  • virtual void OnPing(long lNbMilliseconds);

CNDKMessage: Encapsulation of the data that is sent and received by CNDKServer and CNDKClient

Attributes:

  • void SetId(long lId);
  • long GetId() const;
  • int GetNbElements() const;

Operations:

  • void Add(TYPE typeData);
  • void SetAt(long lIndex, TYPE typeData);
  • void GetAt(long lIndex, TYPE& typeData) const;
  • void GetNext(TYPE& typeData);

Where TYPE can be a UCHAR, char, USHORT, short, UINT, int, long, float, double, CString, or LPVOID data.

What's new in 2.0

  • Hungarian notation is used everywhere
  • CNDKServer notifies automatically CNDKClient when it disconnects and vice-versa
  • CNDKServer has new methods to send a message to a group of users
  • CNDKMessage is easier to use and more robust
  • New methods to ping the server or the client
  • NDK prefix added to all classes to make sure that all class names are unique in your project
  • NDK is standalone or encapsulated in an extension DLL

Client/Server chat

Here are two screenshots of the chat application. Most features of the NDK are shown in both programs.

Client Image

Server Image

Sample code from the chat client

void CChatClientDlg::OnButtonSend() 
{
   if (UpdateData(TRUE))
   {
      // Create the message with a unique Id: ChatText
      CNDKMessage message(ChatText);

      // Add the data into the message
      message.Add(m_strChatInput);

      // Send the message to the server      
      SendMessageToServer(message);

      // Update the UI of the dialog
      AddText(m_strChatInput);

      m_strChatInput.Empty();
      UpdateData(FALSE);
   }
}

Sample code from the chat server

void CChatServerDlg::OnMessage(long lUserId, CNDKMessage& message)
{
   switch (message.GetId())
   {
      //...

      case ChatText:
      {
         CString strNickname;

         // Obtain the nickname stored in the map
         m_mapIdsNicknames.Lookup(lUserId, strNickname);

         CString strText;

         // Get the text encapsulated in the message
         message.GetAt(0, strText);

         // Update the UI of the dialog
         AddText(strNickname + _T(": ") + strText);

         // Prepare the message
         message.SetAt(0, strNickname);
         message.SetAt(1, strText);

         // Send the message to all others users
         SendMessageToAllUsersExceptFor(lUserId, message);
      }
      break;

      //...
   }
}

History

  • 17 December 2006
    • Fixed a bug in NDKMessage concerning the length parameter of the GetAt and GetNext methods.
  • 14 October 2005
    • Telnet connections are now disconnected when a connection sends data to the server. Thanks to Stephan Douglas for the solution.
    • Fixed a bug that resolves socket notification since the NDK uses Visual C++ .NET. After a short time, socket notifications were not send anymore.
    • A verification is now made in the serialization of a CNDKMessage to make sure that the message is really a CNDKMessage.
    • Fixed a bug in the method SendMessageToSomeUsers in the NDKServer.cpp.
    • The project is now converted for Visual C++ .NET.

Fact

In 2002, the NDK was used in two NASA experiments for the Endeavor mission.

Conclusion

You don't have to be a guru of networking to create a client/server application, you only need to understand the above classes.

If you use the NDK in your project, I would really appreciate to receive an E-mail from you. I plan to make a web page of all programs using the NDK.

I would like to thank Yannick Létourneau who helped me in NDK 1.0.

Good Programming!

License

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


Written By
Software Developer (Senior) Mirego
Canada Canada
My name is Sébastien Lachance.

I love C# developing Windows Phone and Windows 8 applications.

When I’m not in front of a computer, my hobbies include playing bridge, poker and other card games, biking, reading technology news.

Comments and Discussions

 
GeneralRe: Sending objects vs primitive message fields Pin
ArchieCoder24-Jul-03 9:29
ArchieCoder24-Jul-03 9:29 
GeneralSetting maximum number of users Pin
speedpacer4-Jul-03 9:00
speedpacer4-Jul-03 9:00 
GeneralRe: Setting maximum number of users Pin
ArchieCoder8-Jul-03 17:50
ArchieCoder8-Jul-03 17:50 
GeneralRe: Setting maximum number of users Pin
speedpacer10-Jul-03 6:20
speedpacer10-Jul-03 6:20 
Generalanother project with ndk Pin
T1TAN28-Jun-03 8:08
T1TAN28-Jun-03 8:08 
GeneralRe: another project with ndk Pin
speedpacer10-Jul-03 6:49
speedpacer10-Jul-03 6:49 
GeneralRe: another project with ndk Pin
T1TAN10-Jul-03 11:34
T1TAN10-Jul-03 11:34 
GeneralRe: another project with ndk Pin
speedpacer10-Jul-03 19:04
speedpacer10-Jul-03 19:04 
Well, I'm mostly guessing and basing a little on experience, as I haven't seen the Kazaa code, but I imagine that the applications are acting as both clients and servers.

Peer-to-peer usually occurs by specifying a specific computer to communicate with, in which case you would need to know the IP address or the hostname of the computer you're calling. When you make the request, it'll send a packet to that computer to see if it's listening. If so, the computer sends back an acknowledgement and the connection is established. This all happens on a port that is specific to the application.

It looks like Kazaa and these other chat-type programs operate a little differently, where they don't know the IP address or hostname of the computer they're calling, so they more or less broadcast the request by enumerating IP addresses and attempt to locate the applications that way.

In Kazaa's case for example, and again, just by what little I've read on their website about Supernodes and such, it sounds like when you install the application, it detects if you have a high speed Internet connection. If so, the "server" part of your application is probably enabled and your application will listen on a predefined winsock port, as well as send connection requests, and will store a list of connected users and local files that it finds.

As others start up in your area, they'll do the same thing and ask you for a list of your users, and so on.

When you start the application the first time, it most likely enumerates a list of TCP/IP addresses from your ISP's local routing tables, and then it starts listening for new connections and sends out a request to all of those IP addresses on a specific port (1214 in Kazaa's case) to see if there are other Kazaa applications listening at those IP addresses. If so, it'll update it's user/file list with the user/file list of that computer and move on to the next one, until it eventually has a fairly complete list.

It's works in sort of the same fashion as broadcasting, except that it's using TCP/IP instead of netbios, which makes it a little more reliable. Chances are, it probably has its own host table as well, where it stores IP addresses (in a flat file or something) on your local computer of other Kazaa "Supernodes" that it's found in the past. So the next time you start it up, it'll send a request directly to those IP addresses first, and then attempt to look for others.

As more Kazaa applications start up across the Internet, the host tables in the routers will naturally keep the routes alive so other Kazaa applications can find each other more quickly and easily.

When you do a search for a specific user that's not already in your user list, it sounds like it'll go out and ask those other Kazaa Supernodes if they've heard of them until it finds one that has, which then checks to see if they're online. The request is probably passed off to other Kazaa applications as the routes get longer, and they'll continue to look for the user while your Kazaa application is simply waiting for acknowledgements.

In other words, say you're located in Los Angeles and you're looking for a user in New York. First, your application will look for the user locally, asking all of the Kazaa applications in Los Angeles first, then spreading out. Then those applications will also send out the request and where it came from (you) so it knows how to let you know when the user is found. Eventually, you'll have searched all over California, then Arizona, Nevada, and so on, until it reaches its way to New York and finds the user or times out, whichever comes first.

When that happens of course, you've just opened up a whole new world of routes to Kazaa applications for yourself and those around you, thus it won't take long before all of the Kazaa applications know of each other's existence. As it becomes more widely used, it learns of more and more applications within your area and will know how to find them quicker the next time.

Routers are set up so that they'll first attempt to route you to shorter distances (the path of least resistance) by associating costs with the lines to which they're connected.

It sounds like it would be a very long process, but we're only talking milliseconds here, considering all of the Supernodes are running with broadband connections.

If you've ever worked with domain controllers, they have a similar logic, where periodically inform the other domain controllers of users who've logged onto a domain or logged off. It's a synchronization process that occurs roughly every 15 minutes by default.

It's sort of like spreading rumors. When you connect/disconnect, you tell those around you, they tell their friends, their friends tell their friends, and so on and so on.

Another thing they may be doing is that they may actually have a centralized "server", though it's not really a server, but simply hosts a list of IP addresses that have been found to be running the Kazaa application. That would be fairly easy to do, as they can get the IP address of your computer when you download the application, sign up for the service, or start it for the first time. It may send your IP address to a host file of some sort that all of the Kazaa applications will look in to find other Kazaa applications. That would be a more efficient way to do it in terms of bandwidth usage, though they claim that there's no centralized server, although it wouldn't really be a server per se, so who knows (besides their developers).

Again, I'm just guessing at all of this, but unless they've come out with some new top-secret invention that nobody's ever heard of, and without a centralized server that you specifically tell your client to connect to, I can't imagine it being possible any other way.

As for your other question, I'm not really following what you're asking. Confused | :confused:

Anyway, hopefully someone else will intervene here and give you their two cents, and then you can go out and buy yourself a cup of coffee! Poke tongue | ;-P No seriously, maybe if enough people get involved, we can all come up with the next best thing for you and you can make millions. Then you can buy us all a cup of joe!

Hope that helps,
Don
GeneralRe: another project with ndk Pin
speedpacer10-Jul-03 19:45
speedpacer10-Jul-03 19:45 
GeneralRe: another project with ndk Pin
T1TAN11-Jul-03 11:30
T1TAN11-Jul-03 11:30 
GeneralRe: another project with ndk Pin
speedpacer11-Jul-03 13:40
speedpacer11-Jul-03 13:40 
GeneralRe: another project with ndk Pin
speedpacer11-Jul-03 13:50
speedpacer11-Jul-03 13:50 
GeneralUm folks problem isn't .net Pin
whbares17-Jun-03 6:44
whbares17-Jun-03 6:44 
GeneralRe: Um folks problem isn't .net Pin
speedpacer10-Jul-03 7:28
speedpacer10-Jul-03 7:28 
GeneralFunny story... to everyone but me. Pin
speedpacer11-Jun-03 8:54
speedpacer11-Jun-03 8:54 
GeneralRe: Funny story... to everyone but me. Pin
ArchieCoder11-Jun-03 9:14
ArchieCoder11-Jun-03 9:14 
GeneralRe: Funny story... to everyone but me. Pin
speedpacer11-Jun-03 9:42
speedpacer11-Jun-03 9:42 
GeneralRe: Funny story... to everyone but me. Pin
ArchieCoder11-Jun-03 9:49
ArchieCoder11-Jun-03 9:49 
GeneralWorks like a champ. Pin
speedpacer11-Jun-03 14:12
speedpacer11-Jun-03 14:12 
GeneralRe: Works like a champ. Pin
ArchieCoder13-Jun-03 7:56
ArchieCoder13-Jun-03 7:56 
GeneralRe: Works like a champ. Pin
speedpacer13-Jun-03 9:40
speedpacer13-Jun-03 9:40 
GeneralGuys, I fixed it with .NET Pin
Djof15-Jun-03 19:26
Djof15-Jun-03 19:26 
GeneralRe: Guys, I fixed it with .NET Pin
cthulhu17-Jun-03 1:32
cthulhu17-Jun-03 1:32 
GeneralRe: Guys, I fixed it with .NET Pin
Djof17-Jun-03 9:06
Djof17-Jun-03 9:06 
GeneralRe: Guys, I fixed it with .NET Pin
cthulhu17-Jun-03 9:19
cthulhu17-Jun-03 9:19 

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.