Click here to Skip to main content
15,886,137 members
Articles / Desktop Programming / MFC
Article

Managing packet-based connections with CPacketConnection

Rate me:
Please Sign up or sign in to vote.
4.67/5 (3 votes)
22 Jul 20023 min read 50.7K   2.1K   22  
CPacketConnection is a class for creating and managing packet-based connections

Sample Image

Introduction:

To establish a connection with other machine(s) and begin sending/getting packets is really simple, there are three basic steps:

  1. Make your own Packet class(es), derived from CPacket
  2. Add runtime info to your CPacket derived class(es)
  3. Register them into the CPacketConnection initialization

Step 1: Making your own packet Class

In this first step, you only have to create a class derived from CPacket and implement its virtual methods.

Note: CPacket is a pure virtual class and all his methods must be correctly implemented to ensure that 
CPacketConnection will run properly.

Let´s see those methods:

GetBuffer()

This member function allocates a buffer and fills it with the packet raw data.
It is recommended to store the pointer in the m_buffer member.

Example:

m_buffer = new BYTE[GetBufferSize()];
((LPDWORD)m_buffer)[0] = PACKET_ID //Packet identifier

//m_data is a member variable with packet data
CopyMemory((LPVOID)(m_buffer+4), &m_data, 4) 
return (LPVOID)m_buffer;
GetBufferSize()

Should return size in bytes of the buffer mentioned before.

Example:

return 8; //PACKET_ID: 4 bytes, Packet data: 4 bytes.
Attach()

Tries to attach a packet buffer to your derived class, returns true if success, else, false.

Example:

if(((LPDWORD)p)[0] == PACKET_ID) {
nickname = CString( (LPCTSTR)(((LPBYTE)p)+4) );
message = CString( (LPCTSTR)(((LPBYTE)p)+14) );
return true;
} else
return false;
ReleaseBuffer()

Should cleanup the buffer previously returned (and stored in m_buffer).

Example:

delete m_buffer;
IsKindOf()

Checks if the given buffer contains a packet of the current type.

Example:

return ((LPDWORD)p)[0] == PACKET_ID;

After implementing the funcions, you can add extended functions and variables to your class, like overloaded constructors (standard constructor MUST be implemented), member data, etc...

Step 2: Adding run-time info to the class

Now you have to add run-time information to your class, adding the following lines to your custom packet class:

header file (.h)

DECLARE_DYNCREATE(classname)

Where classname is the name of your custom packet class. For example:

class CMyPacket : public CPacket {
DECLARE_DYNCREATE(CMessagePacket)
...
}

implementation file (.cpp)

IMPLEMENT_DYNCREATE(classname, CObject)

The same as before.

Step 3: Registering packet classes

The packet type registration is performed using a simple macro called REGISTER_PACKET_CLASS(). To register a packet class, just add a call to this macro in the RegisterPacketClasses private function of the CPacketConnection class:

void CPacketConnection::RegisterPacketClasses() {
    REGISTER_PACKET_CLASS(CMyOwnPacket)
}

Note: Don´t forget to include your packet class header in the CPacketConnection header.

// Include here your custom packet types

#include "MessagePacket.h" //for example

//-------------------------------------

Using the class

The standard lifecycle of a CPacketConnection object is the following: the object is created and the different versions of Create try to establish a connection; several calls to SendPacket and GetPacket functions and the << operator manage the packed data flow; and finally the Close function closes the connection and cleans up the member data (default destructor already does this).

Now, let's have a look on the class member functions:

Create()

There are two overloaded versions of this function, the first takes only a port, and the second a port and a IP address. The first one creates a socket which only receives packets, and the second one prepares the class for receiving and sending packets to the machine specified by the IP address.

SendPacket()

Sends the packet specified by the parameter. Note that the memory block pointed by the parameter will be "deleted" by the CPacketConnection internal management thread. Free or use again these pointers at your own risk!.

GetPacket()

Returns the first packet in the input queue, NULL if no packets are in the queue. This function can be called from the OnIdle method of CWinApp or the

OnTimer
message handler.

operator <<

Exactly the same as SendPacket

Close()

Stops the packet management thread, removes all those packets which are in the input/ouput queue, closes the connection and lets the class instance ready to be destroyed or used again.

Remarks

This class has been tested under Windows 98 SE, but I think it will work under other Windows versions, because is based in the MFC´s CAsyncSocket class. The socket type used is SOCK_DGRAM, which fits to the packet-transfer purposes of this document/class, therefore, the user should check if the peer machine is connected and receives the packets (sending a control or validation packet, for example).

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
Instructor/Trainer
Netherlands Netherlands
Emilio is a Computer Engineer currently working as software engineer in embedded systems.

Main interests are C/C++ programming, algorithmics, compilers, embedded systems, cryptography, and operating systems.

Comments and Discussions

 
-- There are no messages in this forum --