 |
| .NET Framework 2.0 For discussion of the Microsoft .NET Framework 2.0. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the .NET Framework 2.0 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

October 13th, 2008, 01:43 AM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
How to get message headers from a POP3 server?
Hi guys,
I am working on retrieving mails from a pop3 server (currently gmail). The code is as below. It can susseccfully connect to the server and authenticate. It fetches the message details by providing it the message number, though i am not sure how does it assign message number. Now the main problem is that i first want to get the header information like message sender, date, subject, attachment info. This information will be shown as a grid to the user and then the user will select a message which will then be retrieved from the server. How do i get the message header information? Please help.
This is only the relevant code, the entire form-specifc code can be easily understood and is not necessary to put here.
Here POPServ.Text could be like pop.gmail.com, User.Text=a valid email account in gamil, Passw.Text = user password
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Text;
namespace POPapp
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class POPForm : System.Windows.Forms.Form
{
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
else
return false;
}
public static string ReadMessage(SslStream sslStream1, bool MultilineResponse)
{
byte[] buffer = new byte[1024];
int bytes = -1;
StringBuilder messageData = new StringBuilder();
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars;
while (true)
{
bytes = sslStream1.Read(buffer, 0, buffer.Length);
if (bytes <= 0)
break;
chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
if (!MultilineResponse)
break;
else if (messageData.ToString().EndsWith("\r\n.\r\n"))
break;
}
return messageData.ToString();
}
private void ConnectBtn_Click(object sender, System.EventArgs e)
{
// change cursor into wait cursor
Cursor cr = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
// create server POP3 with port 110
//Server = new TcpClient(POPServ.Text,110);
Server = new TcpClient(POPServ.Text, 995);
Status.Items.Clear();
try
{
/////////////////////////////////////////////////////////////////////////
sslStream = new SslStream(Server.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServer Certificate), null);
sslStream.AuthenticateAsClient(POPServ.Text);
string messageData = ReadMessage(sslStream, false);
Status.Items.Add(messageData);
Data = "USER " + User.Text + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, false);
Status.Items.Add(messageData);
Data = "PASS " + Passw.Text + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, false);
Status.Items.Add(messageData);
Data = "STAT" + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, false);
Status.Items.Add(messageData);
Data = "LIST" + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, true);
Status.Items.Add(messageData);
/////////////////////////////////////////////////////////////////////////
// change enabled - disabled button
ConnectBtn.Enabled = false;
DisconnectBtn.Enabled = true;
RetrieveBtn.Enabled = true;
// back to normal cursor
Cursor.Current = cr;
}
catch (InvalidOperationException err)
{
Status.Items.Add("Error: " + err.ToString());
}
}
private void RetrieveBtn_Click(object sender, System.EventArgs e)
{
// change cursor into wait cursor
Cursor cr = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
string szTemp;
Message.Clear();
try
{
// retrieve mail with number mail parameter
Data = "RETR " + Number.Text + CRLF;
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
string messageData = ReadMessage(sslStream, true);
Message.Text = messageData;
// back to normal cursor
Cursor.Current = cr;
}
catch (InvalidOperationException err)
{
Status.Items.Add("Error: " + err.ToString());
}
}
}
}
BaburMan
__________________
BaburMan
|
|
The Following User Says Thank You to baburman For This Useful Post:
|
|
|

October 13th, 2008, 03:07 AM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
The "TOP" command retrieves the headers and an optional number of lines from the message. This is an optional POP3 command, but is supported by most modern mail servers so shouldn't be a problem.
/- Sam Judson : Wrox Technical Editor -/
|
|

October 13th, 2008, 02:08 PM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Sam! Thank you for the reply. But here i encounter another problem. Against one of the client's test account on gmail i get the following response when i use STAT command:
+OK 0 0\r\n
Which means there are 0 messages in his inbox whereas i can see there are 92 messages when i look into them directly through gmail. There are many unread records as well. What's wrong with the code then? Its really annoying to me. Please help.
BaburMan
|
|

October 13th, 2008, 02:33 PM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Yes i popped messages using my own gmail account. Though there are a couple of other issues but definitely i get the results of STAT, LIST and RETR commands successfully.
BaburMan
|
|

October 15th, 2008, 09:21 AM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Ok, now successfully getting mails. Don't know why it wasn't working before. Anyways thank you guys for your suggestions. :)
BaburMan
|
|

January 1st, 2009, 09:44 AM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
DELE doesn't seem to work.
The code has been working successfully. Now the client asked to write code to delete some selected messages. I used dele command. The code follows:
Data = "DELE 2 \r\n";
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, true);
The problem is that the server response is too slow for dele. It takes about 10 minutes to come back and respond for success. Secondly the dele command requires the quit command at the end so that all updation can be committed to the server:
Data = "QUIT \r\n";
szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArr ay());
sslStream.Write(szData, 0, szData.Length);
sslStream.Flush();
messageData = ReadMessage(sslStream, true);
Here the last line which reads the response from the server for quit command causes an exception that says the software that is running in the host machine closed the connection. When i comment out dele command the quit command successfuly ends the session. 
__________________
BaburMan
|
|

January 4th, 2009, 06:27 AM
|
|
Registered User
|
|
Join Date: Dec 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
hi guys..
i m using the above code, but its not worked for me. When i m giving username then in the function " ReadMessage" - the variable bytes gets 0 so because of this it come out from While loop and same happens with the password.
i want to access my gmail acount through progrmming (vb.net/C#.net)
but i am facing problem....
plz help me ...
Thanks and Regards,
Gauri
|
|

January 5th, 2009, 07:14 AM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Configure pop settings in your gmail account.
Gauri!
You have to give proper pop server credentials. Like for gmail i have set the server as "pop.gmail.com" and the port as 995. For gmail, you also need to allow accessing pop mails right from your gmail account. There's a link that says "Settings" somewhere on the top which you have to explore a bit. For other servers i am not sure. Are you able to connect to the pop server? Consider the following lines which connect to the server:
sslStream = new SslStream(Server.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServer Certificate), null);
sslStream.AuthenticateAsClient(POPServ.Text);
string messageData = ReadMessage(sslStream, false);
Here what i get as a response in messageData is "+OK Gpop ready for requests from ...". Which means the pop server connected successfully. If you get a message like this then you are ok and now you should enter correct email and password in the subsequent calls. Let me know if still not working.
__________________
BaburMan
|
|

January 5th, 2009, 07:40 AM
|
|
Authorized User
|
|
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Resolved.
Finally found the reason. It was a little mistake. The lines
messageData = ReadMessage(sslStream, true);
for DELE and QUIT should be slightly modified to
messageData = ReadMessage(sslStream, false);
and here we go. Everything works fine  . In fact the second parameter of ReadMessage() should be set to true only if its command expects multiple- line response from the server.
__________________
BaburMan
|
|
 |