Click here to Skip to main content
15,896,557 members
Articles / Desktop Programming / MFC
Article

rEmail Part 1 - rTCPIP

Rate me:
Please Sign up or sign in to vote.
1.80/5 (5 votes)
22 May 20055 min read 27.5K   343   12   4
rEmail is a set of tutorials I am writing describing how I am building tools to download, interpret and send email messages. rTCPIP is the first of the set and describes a very simple class that uses Windows Sockets to establish and communicate over TCP/IP connections.

Introduction

rEmail is a set of tutorials I am writing, describing how I am building tools to download, interpret and send email messages (Including attachments). rTCPIP is the first of the set. It is a very simple class that uses Windows Sockets to establish and communicate over TCP/IP connections. The future rEmail articles will build on this one and anyone using the fullest only needs to download the source of the latest article and they will have everything they need.

This article may seem like it has an extremely small amount of content. I am writing an article starting with such a basic subject for a number of reasons:

  1. What always kills me when using CodeProject tutorials is that, I download the code and get hundreds of errors. I spend hours correcting the errors instead of learning the subject I am actually interested in. What I prefer doing is a bit by bit approach. Write something, test it and see it working, write the next bit, test that etc. I hope to allow readers to follow this approach instead of throwing the whole lot at them at once.
  2. I am giving tutorials describing how to use components I am developing that someone using the final email project wouldn’t need to know. This is important because some of the later standards used (MIME, SMTP) are complex. I do not intend to produce a complete implementation rather just implement what I need. In theory, someone could gain some insight into the methods I use to solve the problems and could extend the code to deal with parts I haven’t implemented.
  3. This is a work in progress. I am aware that the code referenced in this article may change by the time I publish future articles. This may cause problems. When I have finished the whole project, I plan to come back and rewrite these articles.

Using the code

This is a quick description of how to use the code. It involves creating a console application that connects to a mail server. The effect will be the same as launching Telnet, typing open mail.hostname.com 110, reading the server greeting then sending the QUIT signal.

Download and unzip the code.

  • Create a new Hello world C++ Win32 Console Application (I called mine xxtest).
  • Project -> Settings, and make sure ws2_32.lib is linked to in all configurations.
  • Project -> Insert project into workspace and add the rTCPIP project you downloaded to this workspace.
  • Set the active project to xxtest, then Project -> Dependencies and make xxtest dependent on rTCPIP.
  • Compiling at this point should work fine.

Add a #include directive at the tope of xxtest.cpp to point to rTCPIP_Connection.h.

#include "../rTCPIP/rTCPIP_Connection.h"

Compile this to ensure that you have made no mistakes so far.

Add this code to your main function (Replace mail.somehost.com with your email server's address, and 110 with a different port number if you need to).

rTCPIP_Connection *pCon = new rTCPIP_Connection("mail.somehost.com",110);
if (!pCon->Valid()) {
    delete pCon;
    printf("Couldn't Get a Connection\n");
    return 0;
};
delete pCon;

The construction of this class establishes a connection, and if this has been successful, the destruction will close a connection. I use a stage method in my constructor to determine which bits were successful and where it has failed. You can use the Valid function to check if the class connected OK or not.

If it has failed, you can use GetStatus to retrieve a number. Rather than document what the numbers mean, I have decided to leave the reader to look at the constructor method of the class themselves as the meanings will be obvious. This code should compile and run. If you can’t get a connection, check your firewall settings. Also, try using Telnet to connect to determine where the problem is occurring.

Now add the following code above the last delete statement:

char m_buf[512];
pCon->recv_msg(m_buf,512);
printf("Recieved %s from the server\n",m_buf);

Now run the program. You will notice that there is a lot of junk after the message we got back from the server. This is caused by C++ using ‘\0’ as a terminator and the network using “\n\r”. This problem is simply solved by terminating the string properly. I have a function to do this, Terminate, alter the code so that it reads:

char m_buf[512];
pCon->recv_msg(m_buf,512);
pCon->Terminate(m_buf,512);
printf("Recieved %s from the server\n",m_buf);

Warning: When displaying things for debugging purposes, remember that Terminate will alter the string you have just received. I always copy it to another string in my debug code when I want to display it. Also, using this method will, only display the first line from the server.

Finally, let's tell the server to close the connection and read it’s response. Add the following before the final delete line:

pCon->send_msg("QUIT\n",5);
pCon->recv_msg(m_buf,512);
pCon->Terminate(m_buf,512);
printf("Recieved %s from the server\n",m_buf);

This sends the quit message to the server and reads the response. Note the \n at the end of the line. RFC 1939 says it should be a CRLF pair, (\r\n) but in my experiments, I have found that sometimes this doesn’t seem to work for me but just using \n does.

Again, you can compile and run the code here.

You have seen all but two of the functions in the class. You can replace the send message line with:

sprintf(m_buf,"QUIT");
pCon->send_msg_cstr(m_buf);

This has two advantages. You don’t have to count how many characters you are sending. (It will send all characters up till the ‘\0’ character, and it automatically adds the terminator for you. The disadvantage is that you can’t send it a string literal. You have to copy the string into a buffer first.

So, the complete program to test out this class was:

rTCPIP_Connection *pCon = new rTCPIP_Connection("mail.metcarob.com",110);
if (!pCon->Valid()) {
    delete pCon;
    printf("Couldn't Get a Connection\n");
    return 0;
};

char m_buf[512];
pCon->recv_msg(m_buf,512);
pCon->Terminate(m_buf,512);
printf("Recieved %s from the server\n",m_buf);

sprintf(m_buf,"QUIT");
pCon->send_msg_cstr(m_buf);
pCon->recv_msg(m_buf,512);
pCon->Terminate(m_buf,512);
printf("Recieved %s from the server\n",m_buf);

delete pCon;

printf("Hello World!\n");
return 0;

I hope you didn’t get sore fingers typing that!!!

Points of Interest

While working out how to receive multi line messages from the server, I thought it would be nice if I could check and see if there was any data on the buffer to read, so I added the DataToBeRead function which in theory should tell me this.

In fact, I found it didn’t work. Sometimes it reports data to read when there is no data to be read. (Causing annoying program hangs while it waits for data) other times it insists there is no data to be read and my next line of code successfully reads the server response – Weird!!

History

No further articles in the rEmail series have yet been written.

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
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralWill give it a go Pin
S.H.Bouwhuis7-Jun-05 3:30
S.H.Bouwhuis7-Jun-05 3:30 
GeneralHelp - I can't modify this article Pin
Robert James Metcalf22-May-05 9:53
Robert James Metcalf22-May-05 9:53 
GeneralRe: Help - I can't modify this article Pin
Robert James Metcalf23-May-05 7:36
Robert James Metcalf23-May-05 7:36 
GeneralRe: Help - I can't modify this article Pin
Robert James Metcalf1-Jun-05 9:12
Robert James Metcalf1-Jun-05 9: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.