我已经编写了一个代码,它基本上连接到每个可用的SMTP服务器,除了1.问题是,服务器在多个框架中发送一些消息,例如:
C: EHLO domain
S: 220 smtp.horribleserver.com welcome ESMTP <-- 1 frame
S: 250-STARTTLS <-- 1 frame
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-SIZE 120000000
250 HELP
C: STARTTLS
S: STARTTLS ready
S: 250-AUTH LOGIN PLAIN <-- 1 frame
S: 250-AUTH=LOGIN PLAIN <-- 1 frame
S: 250-SIZE 120000000 <-- 1 frame
S: 250 HELP <-- 1 frame
我尝试重写接收函数来处理多个帧回复:
int ReceiveData()
{
int res, i = 0;
fd_set fdread;
timeval time;
int s = 1;
int iCurrentSize = 0;
time.tv_sec = 5;
time.tv_usec = 0;
char cBuffer[1024] = "";
if (RecvBuf == NULL)
{
return -1;
}
memset(RecvBuf, 0, BUFFER_SIZE);
while (1)
{
FD_ZERO(&fdread);
FD_SET(hSocket, &fdread);
if ((res = select(hSocket + 1, &fdread, NULL, NULL, &time)) == SOCKET_ERROR)
{
FD_CLR(hSocket, &fdread);
return -1;
}
if (res == 0)
{
//timeout
printf("S: %s\n", RecvBuf);
FD_CLR(hSocket, &fdread);
return (iCurrentSize + 1);
}
if (FD_ISSET(hSocket, &fdread))
{
s = recv(hSocket, cBuffer, sizeof(cBuffer), 0);
if (s < 0)
{
FD_CLR(hSocket, &fdread);
return -1;
}
if (iCurrentSize >= BUFFER_SIZE)
{
return -2;
}
memcpy(&RecvBuf[iCurrentSize], cBuffer, s);
iCurrentSize += s;
}
}
}
RecvBuffer
指向大小为BUFFER_SIZE
的堆上的内存。
我已经尝试了超过30秒的超时,但结果总是一样的:
S: 220 smtp.horribleserver.com welcome ESMTP
S: 250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-SIZE 120000000
250 HELP
我期待得到以下内容:
S: 220 smtp.horribleserver.com welcome ESMTP
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-SIZE 120000000
250 HELP
即。一旦超时发生,所有回复都存储在同一个缓冲区中。
知道为什么我的代码没有返回预期的结果吗?
答案 0 :(得分:0)
虽然已在评论中回答,但我会为完整性添加一个答案,但是对于窃取答案感觉有点不好,所以会尽可能地添加它。
对于SMTP,您将连接到端口,然后逐行读取套接字,因此编写ReadLine函数将数据作为字符串返回将是第一步。这个函数只是逐字节读取,直到找到\ r \ n(回车/换行)字节组合。
在初始连接时,您将读取每一行,直到您得到一行包含“220”表示服务器就绪 - 请注意空格,因为服务器就绪横幅(以及后续回复)可以通过在代码后面加一个连字符来实现多行。 所以你可以有像
这样的东西220-xxx
220 Server Ready - this is the end of the reply
您现在发送握手的“EHLO”部分希望获得250回复,因此逐行读取,直到回复行以“250”开头 - 再次注意到该空间,尽管您会注意到,但通常会得到一个“250 START”你会经常收到一堆以“250-”开头的行,然后是250之后的最后一行空间
雅虎邮件服务器目前为我们提供了一个很好的例子:
220 mta1262.mail.bf1.yahoo.com ESMTP ready
250-mta1262.mail.bf1.yahoo.com
250-PIPELINING
250-SIZE 41943040
250-8BITMIME
250 STARTTLS
250 STARTTLS是答复的结尾。
如上所述,这是RFC 5321规范的全部内容。
虽然OP不再需要此解决方案,但我希望它对其他人有帮助。