Go4Expert

Go4Expert (http://www.go4expert.com/)
-   MFC (http://www.go4expert.com/articles/mfc-tutorials/)
-   -   Implementation of pop3 client server using sockets (http://www.go4expert.com/articles/implementation-pop3-client-server-using-t11461/)

aisha.ansari84 19Jun2008 10:35

Implementation of pop3 client server using sockets
 

INTRODUCTION



This code will help us to understand the working of a pop3 client server through sockets.


BACKGROUND



Through this any person can retrive certain details of his mails such as the subject , the size. The person needs to know about his username , his password, IP address of the server, port no. With these details he can quickly check his inbox.

The code



This file is Tpop.hpp file .This contains the Tpop class and its function declaration.

Code: Cpp

//Header Files

# include "winsock2.h"
# include <windows.h>
# include <stdio.h>
#include "commctrl.h"
#include <Ws2tcpip.h>

#define DEFAULTSIZE  1024  ///<contains the size for the amount of message to be retieved in one instance.


class Tpop{

public:

            //constructor of the class.
            Tpop();

    //used to initialise the windows socket.
    int  InitialiseWinsock();

    //used to make the connection with the server.
    int  MakeConnection(char* pServerAdd,char* pPortNo);

    //used to get the last error message.
    char*   GetLastErr();

    //used to set the last error message.
    void    SetLastErr(char* pErrormsg);

    //used to send a command to the server.
    int  SendInformation(char *pCommand , char* pMsg,HWND pHwnd);
   
    //used to close the socket connection.
    void    CloseSocket();

    //used to get the response from the server.
    char*   Getresponse();

    //used to recieve information from the server.
    void    RecvInfoFromServer();

            //destructor of the class.
            ~Tpop();

private:

    char*   vErrormsg;  ///<contains the error message.

    SOCKET  vConnectSocket;   ///<object of the class socket.

    char*   vResponse;  ///<contains the response from the server.

};


This file is Tpop.cpp file used to implement the POP3 client server functionalities.
Code: Cpp

/**
 * InitialiseWinsock() used to initialise the windows socket.
 *
 * This continues into the more detailed description of the function.
 *
 * @return   <int>    returns TRUE if the start up fails, else FALSE. 
 *
 */


int Tpop::InitialiseWinsock()
{

        WSADATA data;      ///<contains the data for start up.
        int result;   ///<contains the result of start up.

    // Initialize Winsock
    result = WSAStartup(MAKEWORD(2,2), &data);
    if (result != 0) {

        printf("WSAStartup failed: %d\n", result);
        return TRUE;

    }

}

/**
 * Tpop() constructor of the Tpop class.
 *
 */


Tpop::Tpop()
{
    //used to initialise the windows socket.
    InitialiseWinsock();

    //allocates memory for vResponse.
    vResponse=(char*)calloc(DEFAULTSIZE,sizeof(char));

    //allocates memory for vErrormsg.
    vErrormsg=(char*)calloc(DEFAULTSIZE,sizeof(char));

}

/**
 * ~Tpop() destructor of the Tpop class.
 *
 */


Tpop::~Tpop()
{

    //used to close the socket connection.
    closesocket(vConnectSocket);

    //frees the memory allocated for vResponse.
    free(vResponse);

    //frees the memory allocated for vErrormsg.
    free(vErrormsg);

}

/**
 * MakeConnection() used to make the connection with the server.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   pServerAdd  contains the ip address of the server.
 *
 * @param   pPortNo            contains the port number of the server.
 *
 * @return   <int>            returns TRUE if the connection is done, else FALSE. 
 *
 */


int Tpop::MakeConnection(char* pServerAdd,char* pPortNo)
{   
       
        struct sockaddr_in server;    ///<to store the server Address
        struct hostent *hp;    ///<to store the information about the server
        unsigned int addr;        ///<contains the server address.
        int iResult;                    ///<to store the value return by connect()


     //intializing variables
    memset( &server, NULL, sizeof( sockaddr_in ) );
    addr    = NULL;

    // Attempt to detect if we should call gethostbyname() or
    // gethostbyaddr()

    // server address is a name
    if ( isalpha( pServerAdd[0] ) ) {   

        hp = gethostbyname( "parvathi" );

    } else {
    // Convert nnn.nnn address to a usable one

        addr = inet_addr( pServerAdd );
        hp = gethostbyaddr( ( char * )&addr, 4, AF_INET );

    }

    // hp is null address does not resolved
    if (hp == NULL ) {

        SetLastErr( "Client: Cannot resolve address" );
        WSACleanup();
        exit(0);

    }
   
    // Copy the resolved information into the sockaddr_in structure
    server.sin_addr.S_un.S_un_b.s_b1=(hp->h_addr_list[0][0]);
    server.sin_addr.S_un.S_un_b.s_b2=(hp->h_addr_list[0][1]);
    server.sin_addr.S_un.S_un_b.s_b3=(hp->h_addr_list[0][2]);
    server.sin_addr.S_un.S_un_b.s_b4=(hp->h_addr_list[0][3]);
    server.sin_family = hp->h_addrtype;
    server.sin_port = htons(110 );

    // open socket
    vConnectSocket = socket( AF_INET, SOCK_STREAM , IPPROTO_TCP );

    if ( vConnectSocket < NULL ) {

        SetLastErr( "Client: Error Opening socket" );
        WSACleanup();
        return 0;

    }
    iResult=connect( vConnectSocket, (LPSOCKADDR) &server, sizeof( server ) );


    if ( iResult == SOCKET_ERROR ) {

        SetLastErr( "Client: connect() failed" );
        WSACleanup();
        return 0;

    }
   
    return 1;
}

/**
 * SetLastErr() used to set the last error message.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   pErrormsg    contains the error message.
 *
 */


void Tpop::SetLastErr(char* pErrormsg)
{
    //copies the error message into vErrormsg.
    strcpy(vErrormsg,pErrormsg);

}

/**
 * GetLastErr() used to get the last error message.
 *
 * This continues into the more detailed description of the function.
 *
 * @return  <char*>    contains the error message.
 *
 */


char* Tpop::GetLastErr()
{

    //returns the message stored in vErrormsg.
    return vErrormsg;

}

/**
 * SendInformation() used to send a command to the server.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   pCommand   contains the command to be send to the server.
 *
 * @param   pMsg      contains the value to be send with the command to the server.
 *
 * @param   pHwnd    contains the handle to the parent window.
 *
 * @return  <int>        if the response is +ok then true ,else false.
 *
 */


int Tpop::SendInformation(char *pCommand , char* pMsg,HWND pHwnd)
{
        char* msgBuf;           ///<to store the message to be sent to the POP3 server

        msgBuf=(char*)calloc(DEFAULTSIZE,sizeof(char));
   
    // add the cammand to the message buffer
    strcpy(msgBuf,pCommand);

    //concatenate the space in the message buffer
    strcat(msgBuf," ");

    //concatenate the arguments for the command
    strcat(msgBuf,pMsg);

    //concatenate the \r\n value to tell the end of message
    strcat(msgBuf,"\r\n");

    //send the mesage to the POP3 server and true if it returns SOCKET_ERROR
    if(send(vConnectSocket,msgBuf,strlen(msgBuf),FALSE)==SOCKET_ERROR){
       
        SetLastErr("There was some error in socket");
    }
    free(msgBuf);
   
    //call the function to recieve the server response
    RecvInfoFromServer();

    if((strcmp(pCommand,"LIST")!=0) && (strcmp(pCommand,"RETR")!=0)){

        MessageBox(pHwnd,vResponse,"MESSAGE",MB_OK);
    }
   
    if(strncmp(vResponse,"+OK",3)==0){
        return TRUE;
    }   

    //Add the last occurred error ,if any, to the  LIST BOX
    MessageBox(pHwnd,vResponse,"MESSAGE",MB_OK);
    return FALSE;
}

/**
 * CloseSocket() used to close the socket connection.
 *
 */


void Tpop::CloseSocket()
{

    //closes the connection with the socket.
    closesocket(vConnectSocket);

}

/**
 * Getresponse() used to get the response from the server.
 *
 * This continues into the more detailed description of the function.
 *
 * @return  <char*>    contains the response from the server.
 *
 */


char* Tpop::Getresponse()
{

    return vResponse;

}

/**
 * RecvInfoFromServer() used to recieve information from the server.
 *
 */



void Tpop::RecvInfoFromServer()
{
    //receives the information from the server.
    recv(vConnectSocket,vResponse,DEFAULTSIZE,0);   
}


This file is Twin.hpp file having its class declaration.

Code: cpp

//Header Files

#include "Tpop.hpp"

#   define  IDC_EDITBOX1                 100      ///<Identifier For username
#   define  IDC_EDITBOX2                 101      ///<Identifier For password
#   define  IDC_EDITBOX3                 102      ///<Identifier For ip address
#   define  IDC_EDITBOX4                 103      ///<Identifier For port no
#   define  IDC_MAILINFO              104      ///<Identifier For mail information receiving button
#   define  IDC_DELETE                    105            ///<Identifier For delete button
#   define  IDC_CONNECT            106         ///<Identifier For connect Button
#   define  IDC_DISCONNECT               107            ///<Identifier For disconnect Button
#   define  IDC_GROUP1                  108            ///<Identifier For 1st Group Box
#   define  IDC_GROUP2                  109            ///<Identifier For 2nd Group Box
#   define  IDC_LISTVIEW     110      ///<Identifier For List View.


class Twin{

public:

    //used to create all the controls for the first group box
    void    CreatecontrolsForFirstGroup(HWND pHwnd);

    //used to create all the labels for the edit boxes.
    void    Createlabels(HWND pHwnd);

    //used to create an edit box to receive the port no.
    void    CreatePortEditBox(HWND pHwnd);

    //used to create an edit box to receive the ip address. 
    void    CreateIPEditBox(HWND pHwnd);

    //used to create an edit box to receive the password.
    void    CreatePasswordEditBox(HWND pHwnd);

    //used to create an edit box to receive the user name.
    void    CreateNameEditBox(HWND pHwnd);

    //used to create the group boxes.
    void    Createopbutton(HWND pHwnd);

    //used to create the group boxes.
    HWND    CreateGroup(HWND pHwnd , int pId,int pXaxis);   

    //used to retireve text from the edit control.
    char*   RetrieveText(HWND pHwnd);

    //used to pop all the elements of the stack.
    void    CreateListView (HWND pHwnd);

    //used to create all the controls for the second group box.
    void    CreatecontrolsForSecondGroup(HWND pHwnd);

    //used to create all the buttons for the second group box.
    void    CreateButtonsForSecondGroup(HWND pHwnd);

};


This file is Twin.cpp file used to create all the windows controls such as edit boxes,buttons,list box .

Code: cpp

#include"Twin.hpp"

//global variable
HINSTANCE ghInstance;

/**
 * CreateLabels() used to create labels for all the controls
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd    Contains the address of the Parent Window
 *
 */


void Twin::Createlabels(HWND pHwnd)
{
    //LABEL FOR THE NAME EDIT BOX
    CreateWindow("Static","USERNAME:",WS_CHILD|WS_VISIBLE|SS_LEFT,40,80,150,
                20,pHwnd,NULL,ghInstance,NULL);

    //LABEL FOR THE PASSWORD EDIT BOX
    CreateWindow("Static","PASSWORD:",WS_CHILD|WS_VISIBLE|SS_LEFT,40,180,150,
                20,pHwnd,NULL,ghInstance,NULL);

    //LABEL FOR THE IP ADDRESS EDIT BOX
    CreateWindow("Static","SERVER IP ADDRESS:",WS_CHILD|WS_VISIBLE|SS_LEFT,40,280,150,
                20,pHwnd,NULL,ghInstance,NULL);

    //LABEL FOR THE PORT NUMBER EDIT BOX
    CreateWindow("Static","PORT NUMBER:",WS_CHILD|WS_VISIBLE|SS_LEFT,40,380,150,
                20,pHwnd,NULL,ghInstance,NULL);


}

/**
 * CreateControlsForFirstGroup() used to create all the controls
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWndContains the address of the Parent Window
 *
 */


void Twin::CreatecontrolsForFirstGroup(HWND pHwnd)
{

    //used to cretae all the labels.
    Createlabels(pHwnd);

    //used to create the edit box to enter the user name.
    CreateNameEditBox(pHwnd);

    //used to create the edit box to enter the password.
    CreatePasswordEditBox(pHwnd);

    //used to create the edit box to enter the server IP address.
    CreateIPEditBox(pHwnd);

    //used to create the edit box to enter the server port number.
    CreatePortEditBox(pHwnd);
   
    //used to create the connect and disconnect buttons.
    Createopbutton(pHwnd);
   
}

/**
 * CreatecontrolsForSecondGroup() used to create all the controls
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWndContains the address of the Parent Window
 *
 */


void Twin::CreatecontrolsForSecondGroup(HWND pHwnd)
{
    //used to create the list view.
    CreateListView(pHwnd);

    //used to create the mail info and delete buttons.
    CreateButtonsForSecondGroup(pHwnd);

}

/**
 * CreateNameEditBox() used to create the edit box to enter the user name.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd    Contains the address of the Window
 *   
 */


void Twin::CreateNameEditBox(HWND pHwnd)
{   
    //CREATES THE EDIT BOX
    CreateWindow("Edit",NULL,WS_CHILD|WS_VISIBLE |WS_BORDER|WS_GROUP|WS_TABSTOP,200,80,180,40,
        pHwnd,(HMENU)IDC_EDITBOX1,  ghInstance,NULL);
}

/**
 * CreatePasswordEditBox() used to create the edit box to enter the password.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd                Contains the address of the Window
 *   
 */


void Twin::CreatePasswordEditBox(HWND pHwnd)
{   
    //CREATES THE EDIT BOX
    CreateWindow("Edit",NULL,WS_CHILD|WS_VISIBLE |WS_BORDER|WS_GROUP|WS_TABSTOP | ES_PASSWORD,200,180,180,40,
        pHwnd,(HMENU)IDC_EDITBOX2,  ghInstance,NULL);
}

/**
 * CreateIPEditBox() used to create the edit box to enter the server ip address.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd    Contains the address of the Window
 *   
 */


void Twin::CreateIPEditBox(HWND pHwnd)
{   
    //CREATES THE EDIT BOX
    CreateWindow("Edit",NULL,WS_CHILD|WS_VISIBLE |WS_BORDER|WS_GROUP|WS_TABSTOP,200,280,180,40,
        pHwnd,(HMENU)IDC_EDITBOX3,  ghInstance,NULL);
}

/**
 * CreatePortEditBox()used to create the edit box to enter the server port number.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd    Contains the address of the Window
 *   
 */


void Twin::CreatePortEditBox(HWND pHwnd)
{   
    //CREATES THE EDIT BOX
    CreateWindow("Edit",NULL,WS_CHILD|WS_VISIBLE |WS_BORDER|WS_GROUP|WS_TABSTOP,200,380,180,40,
        pHwnd,(HMENU)IDC_EDITBOX4,  ghInstance,NULL);
}

/**
 * Createopbutton() used to create the connect and disconnect buttons .
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd                Contains the address of the Window
 *   
 */


void Twin::Createopbutton(HWND pHwnd)
{   
    //CREATES THE CONNECT BUTTON
    CreateWindow("Button","CONNECT",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_TABSTOP ,100,600,100,30,
        pHwnd,(HMENU)IDC_CONNECT,ghInstance,NULL);

    //CREATES THE DISCONNECT BUTTON
    CreateWindow("Button","DISCONNECT",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_TABSTOP ,220,600,100,30,
        pHwnd,(HMENU)IDC_DISCONNECT,ghInstance,NULL);

}

/**
 * CreateButtonsForSecondGroup() used to create getmailinfo and delete button
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd  Contains the address of the Window
 *   
 */


void Twin::CreateButtonsForSecondGroup(HWND pHwnd)
{   
    //CREATES THE GETMAILINFO BUTTON
    CreateWindow("Button","GETMAILINFO",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_TABSTOP ,600,600,100,30,
        pHwnd,(HMENU)IDC_MAILINFO,ghInstance,NULL);

    //CREATES THE DELETE BUTTON
    CreateWindow("Button","DELETE",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_TABSTOP ,720,600,100,30,
        pHwnd,(HMENU)IDC_DELETE,ghInstance,NULL);

}

/**
 * CreateGroup() used to Create group controls
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd    Contains the address of the Parent Window Control
 * @param [in]     pId    Contains the Identifier of the group controls
 * @param [in]     pXaxis   Contains the value of the Xaxis.
 *
 */

 
HWND Twin::CreateGroup(HWND pHwnd , int pId,int pXaxis) 
{
        HWND    TabhWnd;                                        ///<contains the handle of the Group box
        DWORD   style= WS_VISIBLE |WS_CHILD | BS_GROUPBOX ;        ///<contains the style of the group boxes

    TabhWnd = CreateWindow( "BUTTON",
                            "",
                            style ,                                           
                            pXaxis,
                            30,
                            480,
                            650,
                            pHwnd,
                            (HMENU) pId,
                            ghInstance,
                            NULL)
    return TabhWnd;

}

/**
 * RetrieveText() used to retireve text from the edit control
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd        Contains the address of the Window
 *
 */


char* Twin::RetrieveText(HWND pHwnd)
{
        char        *edittext;
        int   textlength;

   
    //Retrieve text length
    textlength = SendMessage( pHwnd,WM_GETTEXTLENGTH,0,0);
    edittext=(char*)calloc(textlength+1,sizeof(char));
   
    //retrieve the string entered in the Edit Control
    SendMessage( pHwnd,WM_GETTEXT,textlength+1,(LPARAM) edittext);

    return edittext;
}

/**
 * CreateListView() used to create List View
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd        Contains the address of the Window
 *
 */

void Twin::CreateListView (HWND pHwnd)
{     
        HWND        LvhWnd;  ///<retieves the handle of the list view which is retrieved while creating.
        LVCOLUMN    LvCol;    ///<Contains information about a column in report view. This structure is used both for                           ///<creating and manipulating columns.
        int  i;
        char        *ColHeader[] = {
                                     "INDEX",
                                     "SIZE",
                                     "RECEIVED FROM"
                                   };
        int   ColIndex;

    InitCommonControls();
    LvhWnd=CreateWindow(    WC_LISTVIEW,
                            "",
                            WS_CHILD | LVS_REPORT  | WS_VISIBLE | WS_BORDER | WS_TABSTOP | WS_VSCROLL,
                            510,
                            70,
                            450,
                            500,
                            pHwnd,
                            (HMENU) IDC_LISTVIEW,
                            ghInstance,
                            NULL );
   
    for( ColIndex=0;ColIndex<3;ColIndex++ )
    {
        //Variable specifying which members contain valid information.
        LvCol.mask=LVCF_TEXT | LVCF_FMT | LVCF_WIDTH;   
        //Alignment of the column header and the subitem text.
        LvCol.fmt=LVCFMT_CENTER;   
        //specifies the address of the buffer that receives the column header text.                
        LvCol.pszText=ColHeader[ColIndex];                           
        //Size in TCHARs of the buffer pointed  by the pszText member.
        LvCol.cchTextMax=strlen(ColHeader[ColIndex]);   
        //Index of subitem associated with the column.
        LvCol.iSubItem=ColIndex;
        //size of each column.
        LvCol.cx=150;   
        //makes the columns in the list view.
        i=ListView_InsertColumn(LvhWnd,ColIndex,&LvCol);
    }
}


This file is Tapp.hpp file which contains the class declaration.

Code: cpp

#include "Twin.hpp"

class Tapp{

public:

                    //used to register the windows class.
                    void    Registerclass(HINSTANCE hPrevInstance,HINSTANCE hInstance);

                            //constructor of the Tapp class.
                            Tapp(HINSTANCE hPrevInstance,HINSTANCE hInstance);

                    //used to create a new window for the windows application.
                    void    Createwindow(HINSTANCE hInstance);

                    //used to retrieve the message generated by the controls.   
                    int  Messageloop();

    //used to process all the events of the windows
    static LRESULT CALLBACK WindowProc( HWND pHwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

                    //used to process the commands of the POP3 .
                    void    ProcessPop3Commands(enum eCommands pCommand,HWND pHwnd);

                    //used to get the various informations of the mail.
                    void    GetMailInfo();

                    //used to retrievethe various details of the mail.
                    void    RetrieveDetails(int pIndex);

                    //used to insert the individual mail details in the list view.
                    void    InsertItemInListView(int pIndex,char* pValue,int pRowindex);

                    //used to delete a mail from the server.
                    void    DeleteMail(HWND pHwnd);

private:

    WNDCLASS    vWc;        ///<contains the window class attributes that are registered by the RegisterClass function

    MSG   vMsg;       ///<structure contains message information from a thread's message queue

    HWND        vHwnd;      ///<handle to window

    BOOL        vRet;      ///<specifing return value of getmessage function

    HINSTANCE   vInstance;  ///<contains the present instance of the windows application.

    Tpop        vPop;      ///<object of Tpop class.

    Twin        vWin;      ///<object of Twin class.

};

/**
* This is the enumeration of the commands used for mail information retrieval.
*
* @note
* <ul>
*     <li> CONNECT  to connect to the server.
*     <li> USER  to verify the user name.
*     <li> PASS  to verify the password.
*     <li> STAT     to count the total number of messages.
*     <li> QUIT  to disconnect the socket.
* </ul>
*
*/


enum eCommands{

    CONNECT,            ///<to connect to the server.
    USER,            ///<to verify the user name.
    PASS,            ///<to verify the password.
    STAT,            ///<to count the total number of messages.
    QUIT                ///<to disconnect the socket.

};


This file is Tapp.cpp file used to implement the class function definitions.

Code: cpp

//header files.
#include "Tapp.hpp"

//global variable redeclaration.
extern HINSTANCE ghInstance;

/**
 * Tapp() constructor of the class Tapp.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   hPrevInstance contains the previous instance of the class.
 *
 * @param   hInstance    contains the present instance of the class.
 *
 */


Tapp::Tapp(HINSTANCE hPrevInstance,HINSTANCE hInstance)
{
    //used to register a new windows class.
    Registerclass(hPrevInstance,hInstance);

    //CreateWindow will return the handle to a new window
    Createwindow(hInstance);

    //function to show the window
    ShowWindow( vHwnd, SW_MAXIMIZE );   

}

/**
 * Registerclass() used to register the windows class.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   hPrevInstance contains the previous instance of the class.
 *
 * @param   hInstance    contains the present instance of the class.
 *
 */


void Tapp::Registerclass(HINSTANCE hPrevInstance,HINSTANCE hInstance)
{

    if( !hPrevInstance ){

        vWc.lpszClassName = "GenericAppClass";      ///<Name to identify the window class.
        vWc.lpfnWndProc = WindowProc;               ///<Pointer to the window procedure for this window class
        vWc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; ///<Specifies the class style(s)
        vWc.hInstance = hInstance;                       
        vWc.hIcon = LoadIcon( NULL, IDI_APPLICATION );   ///<returns the handle to an icon to be loaded on the window
        vWc.hCursor = LoadCursor( NULL, IDC_ARROW );     ///<returns the handle to the cursor that has to be displayed
        vWc.hbrBackground = (HBRUSH)( COLOR_WINDOW+6);   ///<set the background color
        vWc.lpszMenuName = NULL;                         ///<class have no default menu
        vWc.cbClsExtra = 0;                           
        vWc.cbWndExtra = 0;
        RegisterClass( &vWc );                            ///<this will register the class
    }

    ghInstance = hInstance;
}

/**
 * Createwindow() used to create a new window for the windows application.
 *
 * This continues into the more detailed description of the function.
 *
 * @param   hInstance    contains the present instance of the class.
 *
 */


void Tapp::Createwindow(HINSTANCE hInstance)
{
   
    vHwnd=CreateWindow( "GenericAppClass",                      ///<name of the window class
                        "POP3 CLIENT SERVER",                           ///<window name
                        WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL|WS_CLIPSIBLINGS,  ///<specifies the window style
                        0,                                          ///<set the horizontal position of the window
                        0,                                          ///<set the vertical position of the window
                        CW_USEDEFAULT,                              ///<set the width of the window
                        CW_USEDEFAULT,                              ///<set the height of the window
                        NULL,                                       ///<contains valid pointer for child window
                        NULL,                                       ///<class menu is used
                        hInstance,                                  ///<Handle to the instance associated with the window
                        NULL )

    SetWindowLong(vHwnd,GWL_USERDATA,(LONG )this);

}

/**
 * Messageloop() used to create a new window for the windows application.
 *
 * This continues into the more detailed description of the function.
 *
 * @return  <int> returns False if vRet is -1,else wParam of vRet.
 *
 */


int Tapp::Messageloop()
{
   
    //it will be executed if function will return nonzero value
    while( (vRet = GetMessage( &vMsg, NULL, 0, 0 )) != 0 )
    {
        //execute if there is an error otherwise 'else' part is executed
        if (vRet == -1) {                               
           
            return FALSE;
       
        } else {                                       
   
            //translates virtual-key messages into character messages.
            TranslateMessage( &vMsg )

            //dispatches a message to a window procedure
            DispatchMessage( &vMsg );      
        }
    }      

    // returns integer that indicates the additional information of the msg
    return (int)vMsg.wParam;       

}


/**
 * WindowProc procedure
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     phWnd        Contains the address of the Window
 * @param [in]     uMsg   specifies the msg
 *
 * @return      0   returns zero.     
 *
 */



LRESULT CALLBACK Tapp:: WindowProc( HWND pHwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{   
        Tapp *controls;

    controls = (Tapp*)GetWindowLong(pHwnd,GWL_USERDATA);


    switch( uMsg ) {
           
    //call function to create all controls.
    case WM_CREATE:

        //creates the first group.
        controls->vWin.CreateGroup(pHwnd,IDC_GROUP1,20);

        //creates all the controls of the first group.
        controls->vWin.CreatecontrolsForFirstGroup(pHwnd);

        //creates the second group.
        controls->vWin.CreateGroup(pHwnd,IDC_GROUP2,500);

        //creates all the controls of the second group.
        controls->vWin.CreatecontrolsForSecondGroup(pHwnd);
   
        break;
       
    //USED TO CONTROL WINDOW
    case WM_COMMAND:

        //Handling Window Controllers
        switch(LOWORD(wParam)){

        case IDC_CONNECT:

            //handles the submission of the details into the list box on clicking submit

            // hiword(wParam) takes the notification
            if(HIWORD(wParam)==BN_CLICKED){

                //processes all the POP3 commands.
                controls->ProcessPop3Commands(CONNECT,pHwnd);
               
            }

            break;

        case IDC_MAILINFO:

            if(HIWORD(wParam)==BN_CLICKED){

                //used to retrive all the mails information.
                controls->GetMailInfo();

            }

            break;

        case IDC_DELETE:

            if(HIWORD(wParam)==BN_CLICKED){

                //used to delete all the mails as choosen by the user.
                controls->DeleteMail(pHwnd);

            }

        case IDC_DISCONNECT:

            if(HIWORD(wParam)==BN_CLICKED){

                //used to disconnect from the server.
                controls->vPop.SendInformation("QUIT"," ",pHwnd);

            }

        }
        break;
   
    //used to close the window
    case WM_CLOSE:                       

        if((MessageBox(pHwnd, "DO YOU REALLY WANT TO EXIT ?", "Message",MB_OKCANCEL))==IDOK){                   
            //for final exit
            DestroyWindow(pHwnd);
        }
        break;

   

    case WM_DESTROY:                                                   

        // POSTS THE MESSAGE WM_DESTROY TO DESTROY THE CREATED WINDOW.
        PostQuitMessage(0)
        break;
   

    //TO PROVIDE DEFAULT PROCESSING ON ANY WINDOW MESSAGES
    default:   

        return( DefWindowProc( pHwnd, uMsg, wParam, lParam ));       
    }                                                   
    return 0;

}  // END OF WINDOW PROCEDURE()

/**
 * ProcessPop3Commands()  used to process the commands of the POP3 .
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     eCommands        Contains the various POP3 commands
 * @param [in]     pHwnd            contains the parent windows handle. 
 *
 */


void Tapp::ProcessPop3Commands(enum eCommands pCommand,HWND pHwnd)
{
    switch(pCommand) {
   
    case CONNECT:

        char* address;        ///<contains the address of the server.
        char* portno;            ///<contains the port no of the server.

        //handles the submission of the details into the list box on clicking submit
        address=vWin.RetrieveText(GetDlgItem(pHwnd,IDC_EDITBOX3));
        portno=vWin.RetrieveText(GetDlgItem(pHwnd,IDC_EDITBOX4));

        if(vPop.MakeConnection(address,portno)==TRUE){ 

            //frees the memory allocated for address.
            free(address);

            //frees the memory allocated for portno.
            free(portno);

            //retrieves the information from the server.
            vPop.RecvInfoFromServer();

            //ADD THE RETRIEVED TEXT TO THE LIST BOX
            MessageBox(pHwnd, vPop.Getresponse(), "Message",MB_OK);
            //sets the command as USER.
            pCommand=USER;

        }else{

            //frees the memory allocated for address.
            free(address);
            //frees the memory allocated for portno.
            free(portno);

            break;
        }

    case USER:

        {
               char   *username;            ///<contains the name of the user.

               username=vWin.RetrieveText(GetDlgItem(pHwnd,IDC_EDITBOX1));
            if(vPop.SendInformation("USER",username,pHwnd)==TRUE){

                //frees the memory allocated for username.
                free(username);
                //sets the command as PASS.
                pCommand=PASS;
            }else{
               
                //frees the memory allocated for username.
                free(username);
                //sets the command as QUIT
                pCommand=QUIT;
            }
        }

    case PASS:

        {

               char   *password;            ///<contains the password.

            password=vWin.RetrieveText(GetDlgItem(pHwnd,IDC_EDITBOX2));

            if(vPop.SendInformation("PASS",password,pHwnd)==TRUE){

                //frees the memory allocated for password.
                free(password);
                //sets the command as STAT.
                pCommand=STAT;
            }else{

                //frees the memory allocated for password.
                free(password);
                //sets the command as QUIT.
                pCommand=QUIT;
            }
        }

    case STAT:

        if(vPop.SendInformation("STAT"," ",pHwnd)==TRUE){
           
            break;
        }else{
            //sets the command as QUIT.
            pCommand=QUIT;

        }
 
    case QUIT:

        if(MessageBox(pHwnd,vPop.Getresponse(), "Message",MB_OK)==IDOK){
            vPop.CloseSocket();
        }
        break;
 
        }
   
    }

/**
 * GetMailInfo()  used to get the various informations of the mail.
 *
 */


void Tapp::GetMailInfo()
{

        int messages;      ///<contains the total no of messages.

        int i;        ///<variable declaration.   

        char* buffer;      ///<contains information from the server.

    //retrieves the total number of messages.
    messages=atoi((vPop.Getresponse()+4));

    //used to set the memory.
    memset(vPop.Getresponse(),0,DEFAULTSIZE );

    //retrieves the individual details of each message until all the messages are over.
    for(i=1;i<=messages;i++){

        buffer=(char*)calloc(10,sizeof(char));

        buffer=_itoa(i,buffer,10);

        //sends information to retrieve the information from the server.
        vPop.SendInformation("RETR",buffer,vHwnd);

        //used to delay the computer time.
        Sleep(200);

        //used to retrieve the details of the mails.
        RetrieveDetails(i);

        //frees the memory allocated for buffer.
        free(buffer);

    }

}

/**
 * RetrieveDetails()  used to retrieve the various details of the mail.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     pIndex      contains the index of the coloum where the data is to be inserted.
 *
 */


void Tapp::RetrieveDetails(int pIndex)
{

        char* response;  ///< contains the response from the server.

        char* buffer;      ///<contains some part of the response.

        int count=0;        ///<counts the no of fields retrieved for the mail.

        char* temp;   ///<contains the value of a particular field.

        int size=0;   ///<contains the size of a particular field of the message.


    //contains the response from the server.
    response=vPop.Getresponse();   
   
    //works until '>' is found.
    while(*response != '>'){

        //retrieves the index number of the message.
        if(count==0){

            temp=(char*)calloc(5,sizeof(char));

            temp=_itoa(pIndex,temp,10);

        //retrieves the size of the message.
        }else if(count==1){

            response=response+4;

            buffer=response;

            //works until the first space is found.
            while(*response!= ' '){

                size++;
                response++;
            }
            temp=(char*)calloc(size+1,sizeof(char));

            //copies the value, before space into temp.
            strncpy(temp,buffer,size);
            temp[size]='\0';
       
        //retrieves the name of the sender of the message.
        }else if(count==2){

            //retrieves information from the server.
            vPop.RecvInfoFromServer();

            //contains the response from the server.
            response=vPop.Getresponse();
   
            size=0;
            while(*response != '<'){

                response++;

            }
            response++;

            buffer=response;
            while(*response!= '>'){

                size++;
                response++;
            }

            temp=(char*)calloc(size+1,sizeof(char));
            strncpy(temp,buffer,size);
            temp[size]='\0';
           
        }

        count++;

        Sleep(200);

        //inserts the details of the message into the list view.
        InsertItemInListView(count,temp,pIndex);

        //frees the memory allocated for temp.
        free(temp);

    }

    //works until the end of a message is reached.
    do{

        //retrieves information from the server.
        vPop.RecvInfoFromServer();

    }while((strstr(vPop.Getresponse(),"\r\n\r\n.\r\n"))==NULL);

    //resets the memory.
    memset(vPop.Getresponse(),0,DEFAULTSIZE);

}

/**
 * InsertItemInListView()  used to insert the individual mail details in the list view.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     pIndex      contains the index of the coloum where the data is to be inserted.
 *
 * @param [in]     pValue      contains the data to be inserted. 
 *
 */


void Tapp::InsertItemInListView(int pIndex,char* pValue,int pRowindex)
{

        LVITEM      LvItem;               ///<contains the information of the item

   
    LvItem.mask = TVIF_TEXT;           
                LvItem.state= 0;   
                ///<assigning text
                LvItem.pszText =(LPSTR) pValue; 
                ///<assign length of the text
                LvItem.cchTextMax =strlen(pValue);
                ///<contain column index
                LvItem.iSubItem=--pIndex;   
                ///<first column index
                LvItem.iItem =pRowindex-1;         

                //insert first item on 0th column
                if(pIndex==0)
                    ListView_InsertItem(GetDlgItem(vHwnd,IDC_LISTVIEW),(LPARAM) (LPTVINSERTSTRUCT) &LvItem);
                //set value to the other columns
                else
                    ListView_SetItem(GetDlgItem(vHwnd,IDC_LISTVIEW),(LPARAM) (LPTVINSERTSTRUCT) &LvItem);


}

/**
 * DeleteMail()  used to delete a mail from the server.
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]     pHwnd            contains the parent windows handle. 
 *
 */


 void Tapp::DeleteMail(HWND pHwnd)
{
        char* msgindex;     ///<to store the message index in the char format
        int   index;        ///<to store the message index in the int format

    msgindex=(char*)calloc(DEFAULTSIZE,sizeof(char));

    //to retrive the selected message index
    index=ListView_GetSelectionMark( GetDlgItem( pHwnd,IDC_LISTVIEW ));
   
    //true if no item is selected or index have -1 value
    if(index == -1 ) {

        MessageBox(vHwnd, "NO ITEM IS SELECTED", "Message",MB_OK);
        return;

    }   

    ListView_GetItemText(GetDlgItem( pHwnd,IDC_LISTVIEW ),index,0,msgindex,DEFAULTSIZE);
    vPop.SendInformation("LIST",msgindex,vHwnd);
    //send the DELE command with message index to delete the message from the mail box and
    //it retruns true if it deletes the message from the list view also
    if(vPop.SendInformation("DELE",msgindex,vHwnd)==TRUE){

        //remove the message from the list view
        ListView_DeleteItem(GetDlgItem(pHwnd,IDC_LISTVIEW),index);
    }
    free(msgindex);
       
}


This file is socket.cpp file used to implement the POP3 client server.
Code: cpp

#include "Tapp.hpp"

/**
 * WinMain() to register our window class
 *
 * This continues into the more detailed description of the function.
 *
 * @param [in]   hInstance:- Handle to the programs executable module (the .exe file in memory)
 * @param [in]   hPrevInstance:- Always NULL for Win32 programs.Handle to the previous instance of the application
 * @param [in]   lpszCmdLine:- Pointer to a null-terminated string of 8-bit characters.specifying the command line
                               for the application,excluding the program name
 * @param [in]   nCmdShow:- How the window is to be shown
 *
 * @return    <int>  it returns wParam value of each message.      
 *
 */


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
{

        Tapp app(hPrevInstance,hInstance)///<object of the Tapp class.
        int result;       ///<stores the return value.

    //To Register and initialize certain common control window classes
    InitCommonControls();

     //to get the message generated by the controls
    result=app.Messageloop();

    //true if window generated function is WM_QUIT
    if(result==0){

        return FALSE;

    }

}


I feel the code is well self explanatory , but still I will like to explain how the application runs.

When we run the application we find 4 edit boxes with the labels of username, password, Ip address, and port number.After filling all the 4 details we click on the connect button and this connects us with the specified server.

After this we find a GetMailInfo button,on clicking this we get the details of all the new arrived mails.Now if we want to delete a particular mail, we do a single click on that mail
and select it , then we click the delete button .This deletes the mail.But this is a temporary deletion. To save all the changes on the server we press the disconnect button . This is how the pop3 client server is working.

asadullah.ansari 20Jun2008 19:02

Re: Implementation of pop3 client server using sockets
 
Nice One!!!

hussein.sajid 16Jan2012 11:32

Re: Implementation of pop3 client server using sockets
 
I am recently learning socket programming. your code will greatly help to better understand it :). what will be our main file to execute your code to work it accordingly your explanation? I made "socket.cpp" as my main file but unfortunately program crashed after taking input(username,password, ip address and port number) without any exception.

i am grateful for urgent help.

Thankyou


All times are GMT +5.5. The time now is 15:22.