现在发送邮件都要SMTP验证,我要用CSocket写发送邮件的程序,请问如何加入SMTP验证?在线等待,最好有原代码,愿意500分相赠。
解决方案 »
- OnSetCursor什么时候调用的
- 关于创建文本的问题
- 为什么ODBC中的API: SQLExecut老是返回SQL_NEED_DATA?
- 怎样可以使一段文本中的关键字能够高亮显示。
- Vista下DirectSoundCapture8创建DirectSoundCaptureBuffer8有问题
- VC版的朋友各位好,我想从VB转到VC平台。不知道大家有没有这方面的经验?我该从哪开始
- Remote Desktop 管理不了我的远程服务器了!!急,急,急!
- 请问如何接收从某一地址(例如255.255.1.1)发来的数据?
- 请问发送什么消息可以使一个对话框最小化?
- 在浏览器将用户的选择结果提交前写入注册表
- 简单的问题,关于错误处理,大家进来指点一下吧,谢谢
- 从一个对话框(父窗口)点击一个按钮,进入另一个对话框(子窗口),如何去掉父窗口?
Email(Encode) -> a SMTP Relay Server -> Remote SMTP Server(远程邮局)。非常简单,邮件编码后被递送到一个SMTP转交服务器上,该服务器对信件分检(到同一邮局的被放在一起)后,根据优先级以及信件的先后次序被发送到远程邮局的SMTP服务器上。换句话说,只要我们知道了SMTP转交服务器是如何确定远程邮局SMTP服务器的地址的,就可以轻松地将饶开SMTP Relay Server直接递送到远程邮局服务器。
SMTP Relay Server是如何确定远程邮局服务器的地址的呢?如果你熟悉域名解析,就知道是怎么回事了,我们知道电子邮件的地址由两部分构成[email protected],邮箱(postbox)和地址(address.com),给域名服务器发送指令查询"address.com”的远程邮局服务器的地址即可找到远程邮局SMTP服务器的IP 地址,该指令查询是被称作MX(Mail Exchange)邮件交换服务器的地址查询。远程邮局SMTP服务器的地址可能不止一个,这时,你可根据信件优先级的不同,将对应优先级的信件发到对应地址的远程邮局SMTP服务器,当然,你也可以不管三七二十一,随便选一个SMTP服务器发送。查询该域名的MX记录(Mail eXchanger),如163.com的MX记录
http://www.codeguru.com/internet/SimpleDNSResolver.html....(有关认证命令)
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: c3RldmVuX3h1
S: 334 UGFzc3dvcmQ6
C: c3RldmVu
S: 235 go ahead
......
谢谢!原理我已经理解了,你给的URL我没能上去,以后再看。现在的问题是:
1.我如何进行MX查询,用gethostbyname()行吗?你所说的“163.com的MX记录”是不是就是163.com的IP地址,如果不是,我如何“给域名服务器发送指令查询"address.com”的远程邮局服务器的地址”
2.得到了地址后,能不能用原来的方法就可以发送邮件?(方法如下)
BOOL CMailDlg::SendMailMessage(LPCTSTR szServer,
LPCTSTR szFrom,
LPCTSTR szTo,
LPCTSTR szSubject,
LPCTSTR szMessage)
{
// Construct a socket from the derived class
CSocketX theSocket; // And create the socket descriptor
if (!theSocket.Create())
{
AfxMessageBox("Socket creation failed");
return FALSE;
} // Connect to the server
if (!theSocket.Connect(szServer, 25))
{
AfxMessageBox("Could not connect to server");
return FALSE;
} // General purpose strings
CString strCommand;
CString strResponse; // Set timeout to 10 seconds
UINT uTimeOut = 10000; // Read the "HELO" response from the server
if (theSocket.Receive(strResponse, uTimeOut) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
} // and check to see if we're talking to an
// SMTP server
if (strResponse.Left(3) != _T("220"))
{
CString strError = "ERROR: Not a valid SMTP server response\r\n";
strError += strResponse;
AfxMessageBox(strError);
theSocket.Send("QUIT\r\n");
return FALSE;
} // Send the "FROM" line
strCommand = "MAIL FROM:<";
strCommand += szFrom;
strCommand += ">\r\n";
theSocket.Send(strCommand);
// and check the response
if (theSocket.Receive(strResponse, uTimeOut) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR: Sender rejected\r\n";
strError += strResponse;
AfxMessageBox(strError);
theSocket.Send("QUIT\r\n");
return FALSE;
} // Send the "RCPT" line
strCommand = "RCPT TO:<";
strCommand += szTo;
strCommand += ">\r\n";
theSocket.Send(strCommand); // and check the response
if (theSocket.Receive(strResponse, uTimeOut) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR: Recipient rejected\r\n";
strError += strResponse;
AfxMessageBox(strError);
theSocket.Send("QUIT\r\n");
return FALSE;
} // Send the "DATA" line
theSocket.Send("DATA\r\n"); // and check the response
if (theSocket.Receive(strResponse, uTimeOut) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("354"))
{
CString strError = "ERROR: DATA command rejected\r\n";
strError += strResponse;
AfxMessageBox(strError);
theSocket.Send("QUIT\r\n");
return FALSE;
} // Send the "Subject" line
strCommand = "Subject: ";
strCommand += szSubject;
strCommand += "\r\n";
theSocket.Send(strCommand); // No response from server expectd // Send the message data
// This code assumes the message
// data contains CRLF pairs
// where appropriate.
if (theSocket.Send(szMessage) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
} // No response from server expectd // Send the termination line
theSocket.Send("\r\n.\r\n"); // and check the response
if (theSocket.Receive(strResponse, uTimeOut) == SOCKET_ERROR)
{
ReportSocketError(theSocket.GetLastError());
return FALSE;
}
if (strResponse.Left(3) != _T("250"))
{
CString strError = "ERROR: Message body rejected\r\n";
strError += strResponse;
AfxMessageBox(strError);
theSocket.Send("QUIT\r\n");
return FALSE;
} // Send the "QUIT" line
theSocket.Send("QUIT\r\n"); return TRUE;
}CSocketX的头文件:
class CSocketX : public CSocket
{
DECLARE_DYNAMIC(CSocketX);// Implementation
public:
int Send(LPCTSTR lpszStr, UINT uTimeOut = 0, int nFlags = 0);
int Receive(CString& str, UINT uTimeOut = 0, int nFlags = 0);
BOOL SetTimeOut(UINT uTimeOut);
BOOL KillTimeOut();protected:
virtual BOOL OnMessagePending();private:
int m_nTimerID;
};
CSocketX的实现部分:
int CSocketX::Send(LPCTSTR lpszStr, UINT uTimeOut, int nFlags)
{
// If a timeout value was specified, set it
if (uTimeOut > 0)
SetTimeOut(uTimeOut); // Call base class function
int nRet = CSocket::Send(lpszStr, strlen(lpszStr), nFlags); // If we previously set a timeout
if (uTimeOut > 0)
{
KillTimeOut();
// If the operation timedout, set a more
// natural error message
if (GetLastError() == WSAEINTR)
SetLastError(WSAETIMEDOUT);
}
return nRet;
}
int CSocketX::Receive(CString& str, UINT uTimeOut, int nFlags)
{
static char szBuf[256];
memset(szBuf, 0, sizeof(szBuf)); // If a timeout value was specified, set it
if (uTimeOut > 0)
SetTimeOut(uTimeOut); // Call base class function
int nRet = CSocket::Receive(szBuf, sizeof(szBuf), nFlags); // If we previously set a timeout
if (uTimeOut > 0)
{
KillTimeOut();
// If the operation timedout, set a more
// natural error message
if (nRet == SOCKET_ERROR)
{
if (GetLastError() == WSAEINTR)
SetLastError(WSAETIMEDOUT);
}
} // Fill in the CString reference
str = szBuf;
return nRet;
}BOOL CSocketX::OnMessagePending()
{
MSG msg; // Watch for our timer message
if(::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE))
{
// If our timer expired...
if (msg.wParam == (UINT) m_nTimerID)
{
// Remove the message
::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
// And cancel the call
CancelBlockingCall();
return FALSE;
}
}
// Call base class function
return CSocket::OnMessagePending();
}
BOOL CSocketX::SetTimeOut(UINT uTimeOut)
{
m_nTimerID = SetTimer(NULL,0,uTimeOut,NULL);
return m_nTimerID;
}
BOOL CSocketX::KillTimeOut()
{
return KillTimer(NULL,m_nTimerID);
}
还是用控件吧
能人快来take分
先谢过了
奇怪,他问的是怎么实现验证,怎么都回答MX查询呢多两个 Base64 编码不就完了吗,教别人发垃圾邮件啊?
不带命令行,但服务器端用POP3的命令方式。
多谢。