|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionAfter reading Agus Kurniawan's article on using C# to communicate with a POP3 server I decided that I'd get a lot more milage if I built up a class that would act as a POP3 client. I decided to implement methods for each of the standard POP3 commands, with each method returning a string containing the response of the POP3 server (where appropriate.) In some situations the command is not valid so the methods detect this and returns an error message rather then sending the command to the server. The source code accompanying this article contains the class definitions and the demo console application (shown above) shows how to use the class to retrieve from a POP3 mail server. Classes, Methods and PropertiesThe attached source code contains one class: The class Each of these "POPmethods" returns a string containing either the response of the POP3 server or an error message if the command was issues inappropriately. The final public method: connect is used to initialize the connection. The optional POP3 commands: APOP, TOP and UIDL are not implemented.
Soon after I started working on this I realized that all the POP3methods could be implemented with the same 4 basic steps:
I decided to keep track of the current state of the POP session with a property named state with I declared to be of the enumerated type connect_state. You can see these declarations near the top of the class definition. public enum connect_state {disc,AUTHORIZATION,TRANSACTION,UPDATE}; ... public connect_state state=connect_state.disc ; There are three POP states:
public string user; public string pwd; public string pop; public bool error;The mechanisms for connecting to the server (a TcpClient) and sending (a NetworkStream) and receiving (a StreamReader) data I grabbed straight from Agus's code. I even kept the same variable names: //borrowed from Agus Kurniawan's article:"Retrieve Mail From // a POP3 Server Using C#" at http://www.codeproject.com/csharp/popapp.asp private TcpClient Server; private NetworkStream NetStrm; private StreamReader RdStrm; private string Data; private byte[] szData; private string CRLF = "\r\n"; Before we can do anything else we need to establish the connection to the server and get things flowing in the network streams. The is done by calling the public method public string connect() { //Initialize the connection. This code snipped "borrowed" //with some modifications... //from the article "Retrieve Mail From a POP3 Server Using C#" at //www.codeproject.com by Agus Kurniawan //http://www.codeproject.com/csharp/popapp.asp // create server with port 110 Server = new TcpClient(pop,110); try { // initialization NetStrm = Server.GetStream(); RdStrm= new StreamReader(Server.GetStream()); //The pop session is now in the AUTHORIZATION state state=connect_state.AUTHORIZATION ; return(RdStrm.ReadLine ()); } catch(InvalidOperationException err) { return("Error: "+err.ToString()); } } Notice that as soon as the connection is initialized, the session enters the
public string DELE(int msg_number) { string temp; if (state != connect_state.TRANSACTION ) { //DELE is only valid when the pop session is in the TRANSACTION STATE temp="Connection state not = TRANSACTION"; } else { issue_command("DELE " + msg_number.ToString ()); temp=read_single_line_response(); } return(temp); } First off, we know that the private void issue_command(string command)
{
//send the command to the pop server. This code snipped "borrowed"
//with some modifications...
//from the article "Retrieve Mail From a POP3 Server Using C#" at
//www.codeproject.com by Agus Kurniawan
//http://www.codeproject.com/csharp/popapp.asp
Data= command + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
NetStrm.Write(szData,0,szData.Length);
}
private string read_single_line_response()
{
//read the response of the pop server. This code snipped "borrowed"
//with some modifications...
//from the article "Retrieve Mail From a POP3 Server Using C#" at
//www.codeproject.com by Agus Kurniawan
//http://www.codeproject.com/csharp/popapp.asp
string temp;
try
{
temp = RdStrm.ReadLine();
was_pop_error(temp);
return(temp);
}
catch(InvalidOperationException err)
{
return("Error in read_single_line_response(): " + err.ToString ()) ;
}
}
Note, in some cases, some POP3 commands return multi-line responses. To handle these there is also a method named private void was_pop_error(string response)
{
//detect if the pop server that issued the response believes that
//an error has occured.
if(response.StartsWith ("-"))
{
//if the first character of the response is "-" then the
//pop server has encountered an error executing the last
//command send by the client
error=true;
}
else
{
//success
error=false;
}
}
Usage ExamplesThe details of the POP3 protocol are a little beyond the scope of this article. So if you would like to learn more about POP3, I'll just refer you to RFC 1725, which you can find here. Let's look briefly at the demo application to see how the class is used: static void Main(string[] args)
{
POP3Client.POP3client Demo = new POP3Client.POP3client();
Console.WriteLine ("****connecting to server:");
Console.WriteLine (Demo.connect ("your_pop3_server"));
Console.WriteLine ("****Issuing USER");
Console.WriteLine (Demo.USER ("user_id"));
Console.WriteLine ("****Issuing PASS");
Console.WriteLine (Demo.PASS ("password"));
Console.WriteLine ("****Issuing STAT");
Console.WriteLine (Demo.STAT () );
Console.WriteLine ("****Issuing LIST");
Console.WriteLine (Demo.LIST () );
Console.WriteLine ("****Issuing RETR 700...this" +
" will cause the POP3 server to gack a "
+ "hairball since there is no message 700");
Console.WriteLine (Demo.RETR (700) );
// this will cause the pop3 server to throw
// an error since there is no message 700
Console.WriteLine ("****Issuing RETR 7");
Console.WriteLine (Demo.RETR (7) );
Console.WriteLine ("****Issuing QUIT");
Console.WriteLine (Demo.QUIT ());
Console.ReadLine ();
}
In general, you create an instance of the Please be aware that this code come with no warranty of any sort, express or implied. It is provided strictly "as is" and is indended solely for educational purposes. YOU USE IT AT YOUR OWN RISK. By using this code you agree to hold the Author and Restek blameless for any loss resulting from the use of the code. History
|
||||||||||||||||||||||