I'm new here... i've just begun programming with wxWidgets, i'm trying to develop a simple SMTP client, for sending e-mail by SMTP, of course
i create the GUI, and i've associated to the wxButton "Send" the event of connecting to the SMTP server and beginning to exchange messages with the server. Everything is ok until the first command sent to the server (HELO), the server answers correctly (message 250), but when the program sends the second command, the server replies with error 421 and closes connection. Where's the error?
I'm new to wxWidgets and socket programming, so the code is surely full of mistakes... for now the SMTP server is not chosen by the user (it's a Yahoo server). Please I need help!
Sorry for my bad English, i'm a stranger
I post the full code, so you could compile it and see by yourself what happens...
If you please can help me finding where the error is... Thanks!
Code: Select all
#include "wx/wxprec.h"
#include <math.h>
#include <wx/notebook.h>
#include <wx/textfile.h>
#include <wx/textctrl.h>
#include <wx/socket.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#define PORT 25
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE);
void OnClose(wxCommandEvent &event);
void OnClear(wxCommandEvent &event);
void OnSend(wxCommandEvent &event);
void OnQuit(wxCommandEvent &event);
void OnIdle(wxIdleEvent &event);
void OnAbout(wxCommandEvent &event);
void OnSocketEvent(wxSocketEvent &event);
private:
wxToolBar* mainToolBar;
wxTextCtrl* serverInput;
wxTextCtrl* mailFromInput;
wxTextCtrl* rcptToInput;
wxTextCtrl* dataInput;
wxTextCtrl* statusInput;
wxButton* sendButton;
wxButton* cancelButton;
wxButton* clearButton;
wxMenu* menuFile;
wxPanel* panel;
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
enum
{
Minimal_Quit = 1,
Minimal_About = wxID_ABOUT,
ID_ServerInput = 2,
ID_MailFromInput = 3,
ID_RcptToInput = 4,
ID_DataInput = 5,
ID_SendButton = 6,
ID_CancelButton = 7,
ID_ClearButton = 8,
SOCKET_ID = 10,
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWindows
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
EVT_MENU(Minimal_About, MyFrame::OnAbout)
EVT_BUTTON(ID_CancelButton, MyFrame::OnClose)
EVT_BUTTON(ID_SendButton, MyFrame::OnSend)
EVT_BUTTON(ID_ClearButton, MyFrame::OnClear)
EVT_SOCKET(SOCKET_ID, MyFrame::OnSocketEvent)
EVT_IDLE(MyFrame::OnIdle)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame(_T("SMTP Client"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & (wxCAPTION | wxRESIZE_BOX | wxMAXIMIZE_BOX));
frame->Centre(wxBOTH);
frame->Show(TRUE);
return TRUE;
}
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: wxFrame(NULL, -1, title, pos, size, style)
{
#if wxUSE_MENUS
menuFile = new wxMenu;
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog"));
menuFile->Append(wxID_OPEN, _T("&Open\tAlt-O"), _T("Open an input text file"));
menuFile->Append(wxID_SAVE, _T("&Save\tAlt-S"), _T("Save output on a text file"));
menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
menuFile->Enable(wxID_SAVE, FALSE);
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, _T("&File"));
menuBar->Append(helpMenu, _T("&Help"));
SetMenuBar(menuBar);
#endif // wxUSE_MENUS
panel = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
serverInput = new wxTextCtrl(panel, ID_ServerInput, "", wxDefaultPosition, wxSize(200, 20));
wxStaticText* serverLabel = new wxStaticText(panel, -1, "SMTP Server:", wxDefaultPosition, wxDefaultSize);
mailFromInput = new wxTextCtrl(panel, ID_MailFromInput, "", wxDefaultPosition, wxSize(200, 20));
wxStaticText* mailFromLabel = new wxStaticText(panel, -1, "Mail From: ", wxDefaultPosition, wxDefaultSize);
rcptToInput = new wxTextCtrl(panel, ID_RcptToInput, "", wxDefaultPosition, wxSize(200, 20));
wxStaticText* rcptToLabel = new wxStaticText(panel, -1, "Rcpt To: ", wxDefaultPosition, wxDefaultSize);
dataInput = new wxTextCtrl(panel, ID_DataInput, "", wxDefaultPosition, wxSize(200, 100), wxTE_MULTILINE);
wxStaticText* dataLabel = new wxStaticText(panel, -1, "E-mail Text: ", wxDefaultPosition, wxDefaultSize);
statusInput = new wxTextCtrl(panel, -1, "Not connected yet.\nPress \"Send\" when ready...", wxDefaultPosition, wxSize(200, 70), wxTE_MULTILINE);
statusInput->SetEditable(FALSE);
sendButton = new wxButton(panel, ID_SendButton, "Send", wxDefaultPosition, wxDefaultSize);
cancelButton = new wxButton(panel, ID_CancelButton, "Exit", wxDefaultPosition, wxDefaultSize);
clearButton = new wxButton(panel, ID_ClearButton, "Clear All", wxDefaultPosition, wxDefaultSize);
wxFlexGridSizer* frameSizer = new wxFlexGridSizer(3, 1, 20, 20);
wxFlexGridSizer* commandsSizer = new wxFlexGridSizer(6, 1, 10, 10);
wxBoxSizer* serverSizer = new wxBoxSizer(wxHORIZONTAL);
serverSizer->Add(10, 10);
serverSizer->Add(serverLabel, 0, wxALIGN_CENTER);
serverSizer->Add(10, 10);
serverSizer->Add(serverInput, 0, wxALIGN_CENTER);
serverSizer->Add(10, 10);
wxBoxSizer* mailFromSizer = new wxBoxSizer(wxHORIZONTAL);
mailFromSizer->Add(10, 10);
mailFromSizer->Add(mailFromLabel, 0, wxALIGN_CENTER);
mailFromSizer->Add(10, 10);
mailFromSizer->Add(mailFromInput, 0, wxALIGN_CENTER);
mailFromSizer->Add(10, 10);
wxBoxSizer* rcptToSizer = new wxBoxSizer(wxHORIZONTAL);
rcptToSizer->Add(10, 10);
rcptToSizer->Add(rcptToLabel, 0, wxALIGN_CENTER);
rcptToSizer->Add(10, 10);
rcptToSizer->Add(rcptToInput, 0, wxALIGN_CENTER);
rcptToSizer->Add(10, 10);
wxBoxSizer* dataSizer = new wxBoxSizer(wxHORIZONTAL);
dataSizer->Add(10, 10);
dataSizer->Add(dataLabel, 0, wxALIGN_CENTER);
dataSizer->Add(10, 10);
dataSizer->Add(dataInput, 0, wxALIGN_CENTER);
dataSizer->Add(10, 10);
wxStaticBox* statusBox = new wxStaticBox(panel, -1, "Status", wxDefaultPosition, wxDefaultSize);
wxStaticBoxSizer* statusBoxSizer = new wxStaticBoxSizer(statusBox, wxHORIZONTAL);
wxBoxSizer* statusSizer = new wxBoxSizer(wxHORIZONTAL);
statusSizer->Add(10, 10);
statusSizer->Add(statusInput, 1, wxGROW | wxALIGN_CENTER);
statusSizer->Add(10, 10);
statusBoxSizer->Add(statusSizer, 1, wxALIGN_CENTER);
commandsSizer->Add(10, 10);
commandsSizer->Add(serverSizer, 1, wxGROW | wxALIGN_CENTER);
commandsSizer->Add(mailFromSizer, 1, wxGROW | wxALIGN_CENTER);
commandsSizer->Add(rcptToSizer, 1, wxGROW | wxALIGN_CENTER);
commandsSizer->Add(dataSizer, 1, wxGROW | wxALIGN_CENTER);
commandsSizer->Add(statusBoxSizer, 1, wxGROW | wxALIGN_CENTER);
wxBoxSizer* buttonsSizer = new wxBoxSizer(wxHORIZONTAL);
buttonsSizer->Add(cancelButton, 0, wxALIGN_CENTER);
buttonsSizer->Add(clearButton, 0, wxALIGN_CENTER);
buttonsSizer->Add(sendButton, 0, wxALIGN_CENTER);
frameSizer->Add(commandsSizer, 1, wxGROW | wxALIGN_CENTER);
frameSizer->Add(buttonsSizer, 0, wxALIGN_CENTER);
frameSizer->Add(10, 10);
frameSizer->Fit(this);
CenterOnParent(wxBOTH);
SetSizer(frameSizer);
SetAutoLayout(TRUE);
Layout();
SetSize(300, 430);
#if wxUSE_STATUSBAR
CreateStatusBar(2);
SetStatusText(_T("Ready..."));
#endif
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString msg;
msg.Printf(_T("\"SMTP Client\"\n\n")
_T("- Author: Stefano Pace\n\n")
_T("- Compiled with:\n\n")
_T("Dev-C++ v.4.9.9.2\n\n")
_T("- GUI toolkit:\n\n")
_T("%s"), wxVERSION_STRING);
wxMessageBox(msg, _T("About SMTP Client"), wxOK | wxICON_INFORMATION, this);
}
void MyFrame::OnIdle(wxIdleEvent &event)
{
//SetStatusText("Ready...");
}
void MyFrame::OnClose(wxCommandEvent &event)
{
this->Destroy();
}
void MyFrame::OnClear(wxCommandEvent &event)
{
serverInput->SetValue("");
mailFromInput->SetValue("");
rcptToInput->SetValue("");
dataInput->SetValue("");
statusInput->SetValue("Not connected yet.\nPress \"Send\" when ready...");
statusInput->Enable(FALSE);
menuFile->Enable(wxID_SAVE, FALSE);
}
void MyFrame::OnSend(wxCommandEvent& event)
{
wxIPV4address addr;
addr.Hostname(wxT("mx2.mail.yahoo.com"));
addr.Service(PORT);
// Create the socket
wxSocketClient* Socket = new wxSocketClient();
// Set up the event handler and subscribe to most events
Socket->SetEventHandler(*this, SOCKET_ID);
Socket->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG | wxSOCKET_OUTPUT_FLAG);
Socket->Notify(TRUE);
// Wait for the connection event
Socket->Connect(addr, FALSE);
//Socket->WaitOnConnect(10);
/*if (Socket->IsConnected())
{
}
else
{
Socket->Close();
}*/
}
void MyFrame::OnSocketEvent(wxSocketEvent& event)
{
// The socket that had the event
wxSocketBase* sock = event.GetSocket();
// Common buffer shared by the events
char buf[100] = "";
switch(event.GetSocketEvent())
{
case wxSOCKET_CONNECTION:
{
SetStatusText("Connected to SMTP server...");
statusInput->AppendText("\n\nConnected to SMTP server...");
break;
}
case wxSOCKET_INPUT:
{
char nextMessage[50] = "";
static int count = 0;
sock->Read(buf, sizeof(buf));
statusInput->AppendText("\n");
statusInput->AppendText(buf);
const wxChar* temp;
// next command choice...
switch(count)
{
case 0:
{
strcpy(nextMessage, "HELO SMTP Client v1.0\n");
sock->Write(nextMessage, sizeof(nextMessage));
break;
}
case 1:
{
temp = mailFromInput->GetValue();
sprintf(nextMessage, "MAIL FROM:<%s>\n", temp);
sock->Write(nextMessage, sizeof(nextMessage));
break;
}
case 2:
{
temp = rcptToInput->GetValue();
sprintf(nextMessage, "RCPT TO:<%s>\n", temp);
sock->Write(nextMessage, sizeof(nextMessage));
break;
}
case 3:
{
temp = dataInput->GetValue();
sprintf(nextMessage, "DATA\n%s\n.\n", temp);
sock->Write(nextMessage, sizeof(nextMessage));
break;
}
case 4:
{
strcpy(nextMessage, "QUIT\n");
sock->Write(nextMessage, sizeof(nextMessage));
break;
}
}
statusInput->AppendText("\n");
statusInput->AppendText(nextMessage);
count++;
break;
}
// The server hangs up after sending the data
case wxSOCKET_LOST:
{
sock->Destroy();
statusInput->AppendText("\nConnection lost.");
SetStatusText("Connection lost...");
wxString msg;
msg.Printf(_T("Connection lost!"));
wxMessageBox(msg, _T("Error"), wxOK | wxICON_ERROR);
break;
}
case wxSOCKET_OUTPUT:
{
break;
}
}
}