A POP3 client C # class
Author: Bill Dean
Keywords: C #, VB.NET, .NET, INTERNET
Submitted: 2002-02-26
Update: 2003-08-06
Summary: This article describes a C # class that implements standard POP3 commands.
· Download source file - 2 KB
· Download Demonstration - 5 KB
· Download VB.NET version source file (Ronny Reinertsen)
Introduction
After reading Agus Kurniawan's article with C # and POP3 server, I decided that if I created a POP3 client class, I will go further. I decided to implement a method for each standard POP3 command, each method returns a string containing (corresponding) POP3 server response, some case commands are invalid, then these methods check these errors and return an error message instead of direct delivery Command to the server. A source file containing the text contains the definition of the class and a console presentation program that uses the class with the POP3 mail server (listed above).
Class, method and attribute
The supplied source code contains a class: POP3CLIENT.
The POP3Client class contains ten common methods, of which nine representative standard POP3 commands:
· Dele,
· List,
· NOOP,
· Pass,
· Quit,
· Retr,
· Rset,
Stat
· And User
Each "PopMethods" returns a string, the content is (corresponding) POP3 server response result, or an inappropriate command caused by an error message. The last public method: Connect is used to initialize the link. No optional POP3 command: APOP, Top and Uidl.
Shortly after the start of work, I realized that all POP3 methods should be implemented as follows:
1. Check that this command is valid in the current POP state.
2. If it is active, send a command to the server.
3. Read the response result.
4. (if needed) to change the POP status.
I decided to track the current status of the POP session with a property called State, and the data type declared as the enumeration type of Connect_State. You can see these statements at the top of the definition of the class.
Public enum connect_state {disc, authorization, transaction, update};
...
Public connection_state state = connect_state.disc;
There are three POP status: Authorization, Transaction, Update. (Complete POP3 Protocol Definition See the RFC 1725) State property is set to DISC (disconnected) before establishing any connection to the POP3 server, and establish a connection to Authorization.
I Also Thought It Would Be Useful to Store The User Name, Password, Pop Server Name and Error State (i.e .: DID An Error Occur On The Last Pop3 Command), SO i add these Properties to the Class:
I also think that saving username, password, POP3 server name, and error status are useful (for example: determining whether a POP3 command has an error), so I added these attributes in the class:
Public String User; Public String PWD;
Public String Pop;
Public bool error;
Connecting Server (TCPCLIENT), the NetWorkStream and the STREAMReader mechanism are directly taken from the code of the AGUS. I even retain the same variable name:
// By using the article from Agus Kurniawan: "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 doing any other work, we need to build a channel server and obtain information in the network stream. This is carried out in the Connect utility method.
Public String Connect ()
{
// Initialize the connection, this code is a little modification "borrow"
// Articles from Agus Kurniawan at www.codeproject.com
// "Retrieve Mail from a pop3 server using c #"
// at http://www.codeproject.com/csharp/popapp.asp
// Create a server with a 110 port
Server = New TcpClient (POP, 110);
Try
{
// Initialization
NetStrm = Server.getStream ();
RDSTRM = New StreamReader (server.getStream ());
/ / POP session is now set to Authorization status
State = connect_state.Authorization;
Return (RDStrm.Readline ());
}
Catch (InvalidOperationException ERR)
{
Return ("Error:" Err.Tostring ());
}
}
Note: As long as the connection is initialized, the session enters the Authorization state.
As mentioned earlier, nine POP3 methods substantially have the same structure. The source code of the Dele method exhibits this structure.
Public String Dele (int msg_number)
{
String Temp;
IF (State! = connection_state.transaction)
{
// The dele command 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, we know that the dele pop3 command is only valid in the Transaction state, so if the class is not in this state, check the value of the recorded in the state property, then return an error message instead of send a request to the POP3 server. When you send the dele command when you are in other states, you will not damage the POP3 server, just generate internal error information. If you prefer to make the POP3 server generated error message, remove the IF structure leaving only ISSUE_COMMAND () calls. Once the POP session is in the correct state, we use the private method Issue_Command to send the "dele" command to the server. RFC 1725 describes the dele command to return a single line response sent back from the server, and we use method read_single_line_response to read. Both methods are quite straightforward, whether it is to establish a connected server writing or from the establishment of a server that comes from the network stream. Because the POP session status is still Transaction status after executing the dele command, we don't have to worry about changing the State value. For example, please refer to the Pass method of the source code. Private void issu_Command (String Command)
{
/ / Send a command to the POP server, this code is a little modification "borrow"
// Articles from Agus Kurniawan at www.codeproject.com
// "Retrieve Mail from a pop3 server using c #"
// 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 result of the POP server, this code is a little modified "borrow"
// Articles from Agus Kurniawan at www.codeproject.com
// "Retrieve Mail from a pop3 server using c #"
// 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 that in some cases, some POP3 commands returns a multi-line response. Here is a method called Read_Multi_Line_RESPONSE. I have already mentioned before, I think it is useful to determine whether the last POP command is executed correctly, or if the POP3 server returns an error, it will be useful. Here is a WAS_POP_ERROR private method to check.
PRIVATE VOID WAS_POP_ERROR (String Response)
{
/ / Check the POP server responded and considered an error.
IF ("-"))
{
// If the first character is "-"
// then an error occurred while the POP server is executing the last command of the client.
Error = True;
}
Else
{
// Successful
Error = false;}
}
The details of the example POP3 protocol are a bit beyond the scope of this article. So if you want to know more about POP3, I suggest you go to RFC 1725, you can find it here. Let us look at the sample program so that you can use this class: 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));
// If there is no 700 messages, it will cause POP3 to throw an error.
Console.writeline ("**** issuing retr 7);
Console.writeLine (Demo.Retr (7));
Console.writeLine ("**** issuing quit");
Console.writeline (demo.quit ());
Console.readline ();
}
In short, you create an instance of a POP3Client class, use your POP3 server to call the Connect method, you can start sending a command. You will need to call the USER and PASS methods to successfully log in to the server, and you must obtain valid login information before calling other POP3 methods.
I hope that some people find this article is useful. I also want to receive feedback or suggestions.
Please understand that this code does not have any guarantees, whether it is express or hint. The code is stricter "unaffirmation" to provide only for education purposes. Who will use who is responsible. To use this code, please promise any loss brought by the code to be independent of author and restek.
history
2003-08-06 - Ronny Reinertsen enlisted C # version to VB.NET
(Finish)
See Original: POP3 Client AS A C # Class