在 c 中发送电子邮件,服务器在我发送 body 后不再回复

Send an email in c, server never reply after i send the body

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

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

对于每个命令,我收到服务器的答复:250 ****** 但是对于数据,它在第一个 354 中回复,但在最后一个句号之后从不回复 250。我虽然它是与 telnet 相同的协议。 最后的句号 = body 的结尾。 但它不起作用。邮件服务器从不回复。

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

代码

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");
}

在你的 main 中,你必须设置端口 =25,为 server_name 使用真正的 smtp 服务器,并添加一个包含 Winsock2.h

的库

命令:

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 中解释的那样。

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

RFC 821 says

The third step in the procedure is the DATA command.

        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