在C中发送电子邮件,服务器在发送正文后永不回复

时间:2019-01-14 13:57:30

标签: c sockets telnet winsock winsock2

我创建了一个小程序来在c中发送电子邮件。 我做了3个功能: 连接:使用套接字连接到服务器, SendAndRecieve:向邮件服务器发送和接收消息, SendAnEmail:编写将由SendAndRecieve发送的文本。

Connect和SendAndRecieve运行正常。 我的问题是在SendAnEmail中。我不知道如何完成数据步骤。

对于每个命令,我都会收到服务器的答案:250 ****** 但是对于数据,它首先返回354,但在最后的句号停止后永远不会返回250。我虽然与telnet协议相同。 最后的句号=身体的尽头。 但这不起作用。邮件服务器永不回复。

有人知道告诉服务器我写完正文的解决方案吗?

代码

SOCKET connexion(char* server_name,unsigned short port)
{
    char buf[1024]={0};
    int res_l= 0;
    int nbrecv;
    struct sockaddr_in   serverSockAddr;
    struct hostent     * serverHostEnt;
    SOCKET to_server_socket = 0;
    serverHostEnt = gethostbyname( server_name );
    if ( serverHostEnt == NULL )  {
        res_l = h_errno;
        return (SOCKET)-1;         }
    memcpy(&serverSockAddr.sin_addr,serverHostEnt->h_addr, serverHostEnt->h_length );
    serverSockAddr.sin_port = htons( port );/
    serverSockAddr.sin_family = AF_INET;            


/* Create socket */                                        
    to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );

/* connexion request*/
    if( connect( to_server_socket, ( struct sockaddr * ) &serverSockAddr,sizeof( serverSockAddr ) ) < 0 ) 
        return (SOCKET)-3;
    while( !buf[0] ) nbrecv = recv( to_server_socket, buf, 1024, 0 );
    printf("Welcome message : %s\n",buf);
    return to_server_socket;
}

void SendAndReceive(SOCKET to_server_socket, char * messagesend)
{
    char bufreceive[1024];                                                             
    int size,retVal,nbrecv;                                         
    size  = (int)strlen( messagesend );                                                

    // SEND THE MESSAGE
    retVal = send( to_server_socket, messagesend, size, 0 );
    printf("Envoye : %s\n",messagesend)   ;

    // WAIT THE ANSWER    
    memset(bufreceive,0,1024);                                                                                       
    while(!bufreceive[0])  
        nbrecv = recv( to_server_socket, bufreceive, 1024, 0 );
    printf("Recu : %s\n",bufreceive);                                                  
}             

void SendAnEmail(SOCKET sock)
{
    //ehlo
    SendAndReceive(sock, "EHLO localhost\r\n");
    //mail from
    SendAndReceive(sock, "MAIL FROM:<user@adresse.com\r\n");
    //rcpt to
    SendAndReceive(sock, "RCPT TO:<user@adress.com>\r\n");
    /data
    SendAndReceive(sock, "DATA\r\n");
    //Subject : Subject
    //
    //Body
    //.
    SendAndReceive(sock, "Subject : Subject\r\n\r\nBody\r\n.\r\n");
    //quit
    SendAndReceive(sock, "QUIT\r\n");
}

在您的主机中,必须设置端口= 25,将真实的smtp服务器用作server_name,并添加包含Winsock2.h的库


CMD:

Welcome message : 220 mwinf5d05 ME ESMTP server ready

S: EHLO localhost

R: 250-mwinf5d05 hello [10.162.66.36], pleased to meet you
250-HELP
250-AUTH LOGIN PLAIN
250-SIZE 44000000
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 OK

S: MAIL FROM: <blablabla@orange.fr>

R: 250 2.1.0 <blablabla@orange.fr> sender ok

S: RCPT TO: <xapx35@gmail.com>

R: 250 2.1.5 <xapx35@gmail.com> recipient ok

S: DATA

R: 354 enter mail, end with "." on a line by itself

S: Subject: FlashRad

Ceci est un test.
.

当我自己使用telnet时,我希望能够做到:

就像本website中的解释一样。

所以有人知道怎么说我写完尸体吗? 就像telnet的最后句号一样。

1 个答案:

答案 0 :(得分:1)

  

RFC 821说

     

该过程的第三步是DATA命令。

        DATA <CRLF>

     If accepted, the receiver-SMTP returns a 354 Intermediate reply
     and considers all succeeding lines to be the message text.
     When the end of text is received and stored the SMTP-receiver
     sends a 250 OK reply.

     Since the mail data is sent on the transmission channel the end
     of the mail data must be indicated so that the command and
     reply dialog can be resumed.  SMTP indicates the end of the
     mail data by sending a line containing only a period.  A
     transparency procedure is used to prevent this from interfering
     with the user's text (see Section 4.5.2).

因此,您只需要在身体之后的一个周期内发送一条线路。

如果您在DATA之后等待250,那也是一个错误。您先获得354,然后在仅按句点的行之后获得250

RFC 821