Introduction
This sample demonstrates a basic technique of networking
using the TCP/IP protocol. It implements a simple POP3 client
that connects to the POP3 mail server and retrieves the number
of messages in your mailbox.
The sample is based on the Managed C++ Application created by
the VS App Wizard.
All changes are made in the main source file. In our case this is the
POP3Client.cpp file.
All functionality is implemented in the CPOP3Client
class. This class
has four properties:
POP3HostName | POP3 server address, |
UserName | User Name, |
Password | User Password, |
Status | Error message (read-only) |
and public property NumberOfMessages
to retrieve the number
of messages in the mailbox.
The TcpClient
class from the .NET Framework is used to create a client
connection to a remote host. Inside of the NumberOfMessages
function
we create connection, get access to the buffer to read the data,
read the response from the server, and check it. If it is positive value
we return true, otherwise we return false.
bool ConnectToServer()
{
String *strReadBuffer;
StreamReader *streamRead;
if(m_Client != NULL)
{
m_Client->Close();
m_Client = NULL;
}
m_Client = new TcpClient(m_strPOP3HostName, 110);
streamRead = new StreamReader(m_Client->GetStream(), Encoding::ASCII );
strReadBuffer = streamRead->ReadLine();
streamRead->DiscardBufferedData();
if(strReadBuffer->StartsWith("+OK"))
return true;
else
{
m_Client->Close();
m_Client = NULL;
return false;
}
}
The DisconnectFromServer
function just sends a QUIT command to the server.
void DisconnectFromServer()
{
String *strResponse = String::Empty;
SendCommand("QUIT", &strResponse);
m_Client->Close();
m_Client = NULL;
}
After connecting to the server we get access to the mailbox by sending
USER and PASS commands to the server. The SendCommand
class member takes care of this.
It uses two streams one for reading from the socket (an instance of
the StreamReader
class) and another stream for writing to the socket
(an instance of the NetworkStream
class). It writes the command to the output
stream and gets the response from the input streams. For our current needs
it reads only the first line of the response and discards the rest
of the buffer. To get a multiline response, you should read data in a loop
until end of the stream.
bool SendCommand(String *strCommand, String** pstrOutput)
{
Byte outbuffer __gc[];
StreamReader *streamRead;
NetworkStream *streamWrite;
String *strRequest;
strRequest = String::Concat(strCommand, S"\r\n");
streamWrite = m_Client->GetStream();
streamRead = new StreamReader(streamWrite, Encoding::ASCII);
outbuffer = Encoding::ASCII->GetBytes(strRequest);
streamWrite->Write(outbuffer, 0, outbuffer->Length);
*pstrOutput = streamRead->ReadLine();
streamRead->DiscardBufferedData();
return (*pstrOutput)->StartsWith(S"+OK") ? true : false;
}
Inside the main function we read the parameters from a command line
(POP3 server address, user name, and password)
create an instance of a CPOP3Client object
, set its properties based on the
command line parameters and call the NumberOfMessages
method to retrieve
number of messages in the mailbox.
If an error occurs we print whatever useful information we can.
int main(int argc, char *argv[ ])
{
CPOP3Client* pPOP3Client;
int nNrOfMessages;
if(argc != 4)
{
Console::WriteLine(S"Wrong argument number.");
Console::WriteLine(S"Use following command line:");
Console::WriteLine(S"pop3client.exe POP3Hostname username password");
return 0;
}
pPOP3Client = new CPOP3Client();
pPOP3Client->set_POP3HostName(new String(argv[1]));
pPOP3Client->set_UserName(new String(argv[2]));
pPOP3Client->set_Password(new String(argv[3]));
nNrOfMessages = pPOP3Client->GetNumberOfMessages();
if(nNrOfMessages < 0)
Console::Write(String::Concat(S"Error occured: ", pPOP3Client->get_Status()));
else
{
Console::Write(S"You have ");
Console::Write(nNrOfMessages);
Console::WriteLine(S" messages in your mailbox.");
}
return 0;
}
History
16 Oct 2001 - updated source files for VS.NET beta 2