Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The Ultimate TCP/IP FAQ

0.00/5 (No votes)
5 Oct 2007 1  
A selection of frequently asked questions submitted by users of Ultimate TCP/IP

Visit the Ultimate TCP-IP main page for an overview and configuration guide to the Ultimate Toolbox library.

Contents

Introduction

We've placed some answers here to a few of the most common questions folks have asked about when using various aspects of Ultimate TCP/IP.

If you've come across an issue with Ultimate TCP/IP that needed a work-around or a bit of documentation that didn't quite explain all the ins and outs of a particular function call, please feel free to submit it for inclusion &madash; you can be pretty sure it will be of help to someone else out there!

Frequently Asked Questions

HowTo: report file download/upload progress (11/07/2001)

Q: When I upload or download a file using Ultimate TCP/IP CUT_FTPClient or CUT_HTTPClient classes. I would like to be able to show the user the file download/Upload progress. How do I do that using the Ultimate TCP/IP classes?

A: CUT_FTPClient and CUT_HTTPClient are derived from CUT_WSClient. When these classes are calling receive functions, they call the base class's function. When you are receiving the file to disk, the class will call the virtual ReceiveFileStatus to inform you of how much data was downloaded so far &madash; override this call in a derived class to trap file progress notifications.

ReceiveFileStatus will also allow you to decide whether to continue downloading the file or not &madash; if you return TRUE from the overridden function, the class will continue downloading more data. If you return FALSE, the process will be aborted and the ReceiveToFile (e.g.) will return the Aborted by User error.

The same process is used when you are sending a file, through the SendFileStatus function.

Message body appears as an attachment with no name (11/07/2001)

Q: I am using the toolkit for sending SMTP mail. The toolkit is very easy to use, but I cannot get it to work properly with some recipient mail servers.

For example, if I use the toolkit to send mail to an account in a FirstClass server, the message body is presented as an attachment with no name. It is pretty obvious that the error is related to the encoding of the message.

I am not sure if your toolkit is the problem or if the mail server is the problem. I have however never seen this behavior in FirstClass, no matter the origin of the mail, except when the mail is sent using your toolkit, i.e. the mail body appearing as an attachment with no name. However, if I send a mail to for example hotmail with your toolkit everything looks fine!

Is there a work around this issue?

A: When you add a MIME attachment to your message, the text body of the message may shows up as an attachment when delivered by some email servers.

The reason for this issue, is that some email servers expect the text body to be encoded only In 7Bit, or Quoted Printable. And recognize other encoding to be used with attachments only. To work around this limitations of these servers, make sure that the function CUT_MimeEncode ::Encode() in file utmime.cpp, is setting the message body to the correct encoding type. See the following code sample. The default standard encoding type is 7Bit encoding.

MIMEATTACHMENTLISTITEM *msg_body_item = new 

MIMEATTACHMENTLISTITEM;
msg_body_item->next                   = NULL;
msg_body_item->ptrDataSource          = &msg_body;
msg_body_item->lpszName               = new char[2];
msg_body_item->lpszName[0]            = 0;
msg_body_item->lpszContentType        = new char[15];
msg_body_item->nEncodeType            = CUT_MIME_QUOTEDPRINTABLE; 
// or if you want CUT_MIME_7BIT


strcpy(msg_body_item->lpszContentType, "text/Plain");

And make sure that you encode the body using the correct function based on your selection of the encoding type.

So, you must call EncodeQuotedPrintable(msg_body_item, dest); or Encode7bit(msg_body_item, dest); instead of EncodeBase64() in the same function just before you delete the msg_body_item:

// Encode message body to the destination


EncodeQuotedPrintable(msg_body_item, dest);

// Clean up


delete [] msg_body_item->lpszName;
delete [] msg_body_item->lpszContentType;
delete msg_body_item;

HowTo: Read only new messages from POP3 server? (11/06/2001)

Q: Is there a way to retrieve only new messages since the last time I connected to the POP3 Server, without deleting the read messages? How?

A: Yes, you can achieve this by keeping track of the Unique Id of the messages you have already received.

First call POP3Connect() with the valid parameters to connect to your POP3 server then call RetrieveUID(msgNumber) where msgNumber is the number of message to get UID for.

If msgNumber is set to -1 (default) the class will retrieve UIDs for all messages. This call will populate a class internal vector member whose elements can be accessed by calling GetUID().

Having done that you can then compare the list of returned UID's with the list you have already stored the last time you have read your email. If the UID is not among the list of UIDs you have stored, then retrieve the message.

I can't I retrieve new emails if I remain connected to POP3 (11/06/2001)

Q: When I connect to pop3 server using the CUT_POP3Client, I can retrieve my email. But when a new message arrives I don't get notified. Why?

A: This is a normal behaviour of a POP3 client.

Once the POP3 server has determined through the use of any authentication command that the client should be given access to the appropriate maildrop, the POP3 server then acquires an exclusive-access lock on the maildrop, as necessary to prevent messages from being modified or removed before the session enters the UPDATE state.

If the lock is successfully acquired, the POP3 server responds with a positive status indicator. The POP3 session now enters the TRANSACTION state, with no messages marked as deleted.

If the maildrop cannot be opened for some reason (for example, a lock can not be acquired, the client is denied access to the appropriate maildrop, or the maildrop cannot be parsed), the POP3 server responds with a negative status indicator.

After the POP3 server has opened the maildrop, it assigns a message-number to each message, and notes the size of each message in octets. The first message in the maildrop is assigned a message-number of "1", the second is assigned "2", and so on, so that the nth message in a maildrop is assigned a message-number of "n".

This exclusive-access lock allows the new messages to be stored in the maildrop, however, these new messages will not be included in the list of messages available to the client, until the client re-authenticates.

History control class prevents the dialog from appearing (11/06/2001)

Q: I have added The history control class to a dialog based application. I have set up the member of the class to be a CUH_Control, and I called the following function in OnInitDialog():

m_control.AttachHistoryWindow(m_hWnd, IDC_CUSTOM1);

But, the dialog doesn't show up. Why?

A: When you add the CUH_Control as a custom control to your application you need to register it's window class or it may prevent the dialog from showing up.

The History control is a handy class that allows you to log and view your application notification to a file or to the screen. The reason the dialog is not showing up is that you are using the CUH_Control class without registering it's window. To register the window make sure you add the following line to the InitInstance() of the App class:

CUH_Control::RegisterWindowClass(AfxGetInstanceHandle());

Handle web page redirection using CUT_HTTPClient (11/06/2001)

Q: I want to be able to let the user decide whether to allow a redirect when accessing an HTTP server.

A: Redirection happens when a web server response wants to indicates that further action needs to be taken by the user agent in order to fulfill the request submitted by the user.

When a user agent (the browser or an HTTP client) submits a request to a web server, the server may elect to indicate that the requested resource (e.g. Web page) has been moved to a different location. And a new action is required to be taken by the user agent. (Such as requesting a new web page or requesting the resource from different location.) Here we'll show how to allow the user to accept or refuse redirection.

CUT_HTTPClient class has the following virtual function:

virtual BOOL OnRedirect(LPCSTR szUrl);

The default implementation is not to accept redirection. This is done by returning FALSE from this function.

This function is called by the CUT_HTTPClient class to ask if it is OK to request the URL identified by the LPCSTR szUrl parameter. If the you wish to submit a GET request for the specified URL. Then simply return TRUE from this function. The code below shows how a user might be notified of a redirect:

#include "stdafx.h"


#include <windows.h>


#include <iostream.h>


#include "http_c.h"


class MyHttp: public CUT_HTTPClient
{
public:
    MyHttp(){}

    // overrides the default OnRedirect implementation


    BOOL OnRedirect(LPCSTR szUrl)
    {
        char msgText[2*URL_RESOURCE_LENGTH];
        // ask the user if redirection is ok


        sprintf(msgText, "The server is requesting a redirect to" + 
            "\r\n\"%s\"\r\n continue?",szUrl);

        // show the Message Box


        if ( MessageBox(NULL,msgText,"Page Redirect!",MB_YESNO) == IDYES )
            return  TRUE; // go ahead get the redirection


        else
            returnFALSE; // no don't continue with redirection


    }
};

int main()
{
    MyHttp web;
    // user has accepted redirect, if asked, at this point


    if (web.GET("msdn.microsoft.com/123") == UTE_SUCCESS)
    {
        // First Display the header of the server response


        long     count = web.GetHeaderLineCount();
        long      loop = 0;
        LPCSTR line;

        // loop through all header lines and display them to user


        for ( loop =0;loop < count; loop++ )
        { 
            line = web.GetHeaderLine(loop);
            if (line != NULL)
                cout << line << endl;
        }

        cout <<    endl;
        // body parts


        count = web.GetBodyLineCount();

        // loop through all body lines and display them to user


        for    (loop =0;loop < count;loop++)
        {
            // display line


            line = web.GetBodyLine(loop);

            if     (line != NULL)
                cout << line << endl;
        }     
    }
}

Send email to a password protected SMTP server (11/02/2001)

Q: How do I send an email to a password protected SMTP server?

A: To prevent mass mailing, some SMTP servers implement password access. This article article show you how to connect to an ESMTP server that requires a password.

Mass mailings or 'spamming' is usually achieved by relaying mail through an external mail server, this allows the spammer to use the resources of someone else's computers/network to reach a large number of email addresses without incurring any expense and damage to their own resources. With systems such as MAPS RBL networks identified that they are open for relaying and are therefore a target for spammers to use for mail relaying, these networks can then be blocked from sending mail, causing mail delivery problems for valid users who have done nothing wrong.

Authentication SMTP is an ESMTP extension that allows a client mail application to specify a means of authenticating with an SMTP server, rfc2554 details the implementation of this SMTP extension.

The Authentication Extension to SMTP addresses this problem by allowing mail clients to authenticate themselves with an SMTP server using a username and password, this will allow open relays to be closed off and also give roaming users the ability to continue using a single SMTP server without having to be concerned with being blocked.

When you attempt to send an email to this type of Servers without authenticating first, you may receive the following response:

530 Authentication required

This response may be returned by any command other than AUTH, EHLO, HELO, NOOP, RSET, or QUIT. It indicates that server policy requires authentication in order to perform the requested action.

The Ultimate TCP/IP supported authentication mechanisms are CRAM-MD5 and LOGIN.

The following sample demonstrates how to use the Ultimate TCP/IP CUT_SMTPClient class to connect to a password protected Email Server:

#include "stdafx.h"


#include "smtp_c.h"


#include 



int main ()
{
    // SMTP Client instance


    CUT_SMTPClient mailSender;

    // Set the user Name String


    mailSender .SetUserName (STRING_USER_ACCOUNT);

    // Set the password string


    mailSender .SetPassword (STRING_ACCOUNT_PASSWORD);

    // My server needs authentication 


    mailSender .EnableSMTPLogin(TRUE);


    // If we connected fine then we have authenticated without a problem


    int rt = mailSender .SMTPConnect ( "MY_ESMTP_SERVER_NAME_ORADDRESS",
        "MY_MACHINE_NAME");

    // Display comnnection result


    cout << " Connection " << CUT_ERR::GetErrorString (rt) << endl;

    // if we connected then send email message     


    if (rt == UTE_SUCCESS)
    {
        cout << CUT_ERR::GetErrorString(mailSender .SendMail ( 
            "To_emailaddress","From_EmailAddress", 
            "Testing through Server" ,
            "Hello,\r\n This is a test Message using the modified" + 
            "class\r\n Kindest regards\r\n Self",
            "CC_EmailAddress",NULL) ) << endl;
        // close the connection


        smtp.SMTPClose ();
    }
    return 0;
}

Transfer data using FTP with the client behind a firewall. (07/24/2001)

Q: How do I transfer data when the client is behind a firewall?

A: First set the FireWallMode property to TRUE and then connect to the proxy using the proxy address as the host name (e.g. the hostname argument). Also set the userName parameter as "Userid@TargetServer".

For example:

SetFireWallMode(TRUE);
FTPConnect("[put proxy Addresshere]","code-string" href="%3Cspan">"mailto:anonymous@ftp.microsoft.com">anonymous@ftp.microsoft.com,
    "anonymous@anonymous.com");

HowTo: Request an Email Read Receipt (06/23/2000)

Q: When sending an email message using Ultimate TCP/IP, how do I request that a receipt is sent back to me to confirm that the user has read the email message?

A: The process of requesting read receipt conformation is achieved by adding an Internet Message Header to the delivered message. The name of this header is "Disposition-Notification-To:". This header expects a parameter of an email address to which the read receipt is to be sent. When a (RFC 2298 compliant) email client (such as MS Outlook) receives a message with this header, it prompts the user if the receipt is to be sent back to the original sender. Upon the user's approval, a new email message is composed. This email message will be a MIME encoded message. The message will contain a text attachment report informing the original sender that the message was displayed.

Note that this notification does not mean that the user has read the message. it is just to confirm that the message was displayed by the recipient.

This code shows the addition of the custom header to the message before sending:

#include "stdafx.h"


#include "smtp_c.h"


#include "utMessage.h"


// we need to include the CUT_Msg class



using namespace std;

int main(){

     CUT_SMTPClient smtp;

     CUT_Msg msg; // our one and only message object 



     // add the From Field


     msg.AddHeaderField ("the_from_field@somwhere.com",UTM_FROM); 

     // add the To Field


     msg.AddHeaderField ("the_to_field@somehwere.com",UTM_TO); 

     // add the subject Field


     msg.AddHeaderField ("This is the Subject",UTM_SUBJECT); 

     // Add the Custom Header to ask for Read Receipt


     msg.AddHeaderField ("the_person_to_beNotified@somewhere.com", 
         UTM_CUSTOM_FIELD, "Disposition-Notification-To:");   

     // set the message body 


     msg.SetMessageBody ("Hi\n\tThis is my first message." +
         "\nI love TCP/IP \n\t yours Truly" ); 

     int errorCode = UTE_SUCCESS; 
     errorCode = smtp.SMTPConnect ("Your_email_SMTP_server");
     if (errorCode == UTE_SUCCESS) 
     {
         errorCode = smtp.SendMail (msg); 
         if (errorCode == UTE_SUCCESS) { 
             cout << "Message was Sent" << endl;
         }else 
             cout << CUT_ERR::GetErrorString (errorCode)<< endl; 
     } 
     else 
         cout << CUT_ERR::GetErrorString (errorCode) << endl; 

     smtp.SMTPClose();

     return 0;
}

HowTo: Switch Secure FTP Server to Implicit or Explicit SSL (11/08/2001)

Q: I need to enable my clients around the globe to upload documents to my ftp servers over SSL/TLS. Since I don't have control over which client application (sometimes shareware) they will be using, I want to create servers that support both mechanisms of FTP over SSL (Explicit Security and Implicit Security). Can Ultimate TCP/IP allow me to do that?

A: When both a client and server support SSL or TLS, the utilization of security is accomplished through a sequence of commands passed between the two machines. When using FTP over SSL there are at least two distinct mechanisms by which this sequence is initiated: Explicit (active) and Implicit (passive) security.

Explicit Security

When Explicit security is used, the FTP client must issue a specific command to the FTP server after establishing a connection to establish the SSL link. In this implementation, the default FTP server port is used. The default setting of the CUT_FTPServer class employs this mechanism.

Implicit Security

The other mechanism is Implicit security which is a mechanism by which security is automatically turned on as soon as the FTP client makes a connection to an FTP server. This will require that the client start the negotiation as soon as the socket connection is established. In this case, the FTP server defines a specific port for the client (usually 990) to be used for secure connections.

As of version 4.x CUT_FTPServer class has been updated with a new function to accommodate selection of the security type:

// Sets the FTP Connection to use SSL from the start or to 



wait for 
// negotiation


void SetFtpSslConnectionType(
    enumFtpSSLConnectionType type = FTP_SSL_EXPLICIT);

This function will take one of two enumerations of type enumFtpSSLConnectionType. this enumeration is defined as:

typedef enum enumFtpSSLConnectionType 
{
    FTP_SSL_EXPLICIT,
    //Explicit = SSL After we do the nogotiation



    FTP_SSL_IMPLICIT
    //SSL All the way from the minute we are connecting


}
enumFtpSSLConnectionType;

Broadcast a message to all connected client from server (11/02/2001)

Q: How can I send a message to all connected clients from the server class?

A: The CUT_WSServer class maintains a linked list of all open sockets (clients) that you can iterate through to service the connections. A broadcast method might look like this:

bool CMyWSServer::BroadcastServerMessage()
{
    ::EnterCriticalSection(&m_criticalSection);

    UT_THREADLIST* pItem = m_ptrThreadList;

    // Check to see if the list is empty


    while(pItem != NULL) 
    {
        MSAASSERT(pItem->WSThread != NULL);

        CMyWSThread * pConnection = (CMyWSThread *)pItem->WSThread;

        pConnection->Send("This is a message from server\r\n");

        pItem = pItem->next 
    }
    ::LeaveCriticalSection(&m_criticalSection);

    return true;
}

History

Initial CodeProject release October 2007.

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