rustyd Posted March 31, 2005 Posted March 31, 2005 Hi, New to the sockets stuff and I have some questions about attempting to retrieve email via a .NET application. I've read quite a few posts about sending email, but the receiving posts seem to say they have a problem and subsequent posts recommend Email components or they figured it out themselves with no solution. So, here we go a journey to create my own email component. First, using sockets do I connect to my mail server? I've read some posts about listening on port 110. So, I connect to mail server, then listen on port 110. Am I on the right track? Any help is appreciated. Thanks Quote rustyd
Administrators PlausiblyDamp Posted March 31, 2005 Administrators Posted March 31, 2005 Other way round, the mail server (if it is POP3) will listen on 110 - you will need to connect to it. Most of the work involved is simple comands that would be sent / received as simple ASCII text over a connection to port 110. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
rustyd Posted March 31, 2005 Author Posted March 31, 2005 (edited) Found a C# example and converted to VB.NET I found a C# example and converted to VB.NET. I can't get it to connect to my mail server. The Connect(mailsite, 110) doesn't error out, but when I get the response I get the error: Operation not allowed on non-connected sockets I have a form with 3 textboxes (mailserver, user,pass) and a button that when clicked calls a routine GetMail. GetMail creates and instance of my Pop3 class which inherits Net.Sockets.TcpClient and I call the overloaded function Connect(mailserver, 110). Once the Connect call is made it returns and I call Response() which uses the NetworkStream object and GetStream(). This is where the error occurs. I've include the exact error message and the entire Pop3 class. Here is the exact error message: System.InvalidOperationException: Operation not allowed on non-connected sockets. at System.Net.Sockets.TcpClient.GetStream() at TestMail.Pop3.Response() in C:\Documents and Settings\Rusty\My Documents\Visual Studio Projects\TestMail\Pop3.vb:line 141 at TestMail.Pop3.Connect(String server, String username, String password) in C:\Documents and Settings\Rusty\My Documents\Visual Studio Projects\TestMail\Pop3.vb:line 13 at TestMail.Form1.GetMail() in C:\Documents and Settings\Rusty\My Documents\Visual Studio Projects\TestMail\Form1.vb:line 130 Here is my class: Public Class Pop3 Inherits System.Net.Sockets.TcpClient Public Overloads Sub Connect(ByVal server As String, ByVal username As String, ByVal password As String) Dim message As String Dim response1 As String Dim x As New Net.Sockets.TcpClient() x.Connect(server, 110) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If message = "USER " + username + vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If message = "PASS " + password + vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If End Sub Public Sub Disconnect() Dim message As String Dim response1 As String message = "QUIT" & vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If End Sub Public Function List() As ArrayList Dim message As String Dim response1 As String Dim retval As New ArrayList() message = "LIST" & vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If Do While (True) response1 = Response() If (response1 = "." & vbCrLf) Then Return retval Else Dim msg = New Pop3Message() Dim seps As Char = "' '" Dim values() As String = response1.Split(seps) msg.number = Int32.Parse(values(0)) msg.bytes = Int32.Parse(values(1)) msg.retrieved = False retval.Add(msg) 'continue() End If Loop End Function Public Function Retrieve(ByVal rhs As Pop3Message) As Pop3Message Dim message As String Dim response1 As String Dim msg = New Pop3Message() msg.bytes = rhs.bytes msg.number = rhs.number message = "RETR " + rhs.number + vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If msg.retrieved = True Do While (True) response1 = Response() If (response1 = "." & vbCrLf) Then Exit Do Else msg.message += Response() End If Loop Return msg End Function Public Sub Delete(ByVal rhs As Pop3Message) Dim message As String Dim response1 As String message = "DELE " + rhs.number + vbCrLf Write(message) response1 = Response() If (response1.Substring(0, 3) <> "+OK") Then Dim Pop3Ex As Pop3Exception Pop3Ex.Pop3Exception(response1) End If End Sub Private Sub Write(ByVal message As String) Dim en = New System.Text.ASCIIEncoding() Dim WriteBuffer(1024) As Byte WriteBuffer = en.GetBytes(message) Dim stream As Net.Sockets.NetworkStream stream.Write(WriteBuffer, 0, WriteBuffer.Length) Debug.WriteLine("WRITE:" + message) End Sub Private Function Response() As String Dim enc = New System.Text.ASCIIEncoding() Dim serverbuff(1024) As Byte ' ********************** ' ERROR OCCURS ON THIS LINE Dim stream As Net.Sockets.NetworkStream = GetStream() Dim count As Integer = 0 Do While (True) Dim buff(2) As Byte Dim bytes As Integer = stream.Read(buff, 0, 1) If (bytes = 1) Then serverbuff(count) = buff(0) count += 1 If (buff(0) = vbLf) Then Exit Do End If Else Exit Do End If Loop Dim retval As String = enc.GetString(serverbuff, 0, count) Debug.WriteLine("READ:" + retval) Return retval End Function End Class Edited March 31, 2005 by rustyd Quote rustyd
Mister E Posted April 1, 2005 Posted April 1, 2005 It sounds like you're not connected to the server. I would get rid of everything else and concentrate on establishing a TCP connection with the mail server first. Once you have that you can gradually add functionality and test things incrementally. A good way to practice POP3 commands is to telnet into the mail server and then send the commands by typing them in by hand on your telnet client. The remote mail server should respond and send you back some ASCII characters containing the email header, body, and other things. This will give you an idea of how the information is flowing and will allow you to better understand the process of handling the raw bytes for the connection. I believe RFC 1939 is the one that lists the POP3 specification. Quote
rustyd Posted April 1, 2005 Author Posted April 1, 2005 Telnet vs. My app I can connect successfully via telnet with the command: open mymailserver 110 responds with: +OK Hello There! I overload the connect method in my Pop3 class and use: Connect(mailserver, 110) I get the error: Operation not allowed on non-connected sockets I change the Connect to: Connect("open " + mailserver, 110) I get the error: System.Net.Sockets.SocketException: The requested name is valid and was found in the database, but it does not have the correct associated data being resolved What do you make of this? Quote rustyd
rustyd Posted April 1, 2005 Author Posted April 1, 2005 On to the next problem Wanted to report that I remembered reading a post about someone having problems with their sockets program and they were told about mscorcfg.exe to setup permissions for the program. I added TestMail.exe to the applications and I can connect!! OK, enough of the good news. Now I have problems in the Response() call. It crashes on the line If (buff(0) = vbLf) Then I'm comparing a byte to a string. So, I'll get this figured out. Thanks for your help so far. Quote rustyd
rustyd Posted April 1, 2005 Author Posted April 1, 2005 Yeah!! Got it to connect. Fixed the Response() function. Now onto getting it to pull emails. Quote rustyd
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.