Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过C套接字编程实现邮件格式_C_Email_Smtp_Mime_Winsock2 - Fatal编程技术网

通过C套接字编程实现邮件格式

通过C套接字编程实现邮件格式,c,email,smtp,mime,winsock2,C,Email,Smtp,Mime,Winsock2,我正在学习C语言中的socket编程,学习的最好方法就是实现它。因此,我编写了一个简单的程序,通过C套接字编程发送带有附件和一些文本正文的邮件。到目前为止,该代码只存在一个例外——格式化。MIME标题显示在邮件正文中(附屏幕截图),邮件主题混乱不堪 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <winsock2.h> #inclu

我正在学习C语言中的socket编程,学习的最好方法就是实现它。因此,我编写了一个简单的程序,通过C套接字编程发送带有附件和一些文本正文的邮件。到目前为止,该代码只存在一个例外——格式化。MIME标题显示在邮件正文中(附屏幕截图),邮件主题混乱不堪

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

#define SMTP_PORT "25"
#define DEFAULT_BUFLEN 1024

int sendData(SOCKET* socket, const char* data)
{
    int iResult;
    printf("%s", data);
    iResult = send(*socket, data, (int)strlen(data), 0);
    if (iResult == SOCKET_ERROR) {
        printf("send failed (msg: %s): %d\n", data, WSAGetLastError());
    }
    return iResult;
}

void recvData(SOCKET* socket)
{
    int recvbuflen = DEFAULT_BUFLEN;
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    iResult = recv(*socket, recvbuf, recvbuflen - 1, 0);
    printf("In recvData function: %d\n", iResult);
    if (iResult > 0) {
        recvbuf[iResult] = '\0';
        printf("%s", recvbuf);
    }
    else if (iResult == 0)
        printf("Connection closed\n");
    else
        printf("recv failed: %d\n", WSAGetLastError());
}

int main(int argc, char** argv)
{
    WSADATA wsaData;

    int iResult;
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    iResult = getaddrinfo("mail.sharklasers.com", SMTP_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    SOCKET ConnectSocket = INVALID_SOCKET;
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed: %ld\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }

        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }
    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    sendData(&ConnectSocket, "HELO mail.sharklasers.com\r\n");
    recvData(&ConnectSocket);
    sendData(&ConnectSocket, "MAIL FROM: psgibrxp@sharklasers.com\r\n");
    recvData(&ConnectSocket);
    sendData(&ConnectSocket, "RCPT TO: psgibrxp@sharklasers.com\r\n");
    recvData(&ConnectSocket);
    sendData(&ConnectSocket, "DATA\r\n");
    recvData(&ConnectSocket);
    sendData(&ConnectSocket, "Subject:This is subject of my mail\r\n");
    sendData(&ConnectSocket, "And this is text\r\n");
    sendData(&ConnectSocket, "MIME-Version: 1.0\r\n");
    sendData(&ConnectSocket, "Content-Type:multipart/mixed;boundary=\"KkK170891tpbkKk__FV_KKKkkkjjwq\"\r\n");
    sendData(&ConnectSocket, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n");
    sendData(&ConnectSocket, "Content-Transfer-Encoding: quoted-printable\r\n");
    sendData(&ConnectSocket, "Content-Type: text/plain;name=\"details.txt\"\r\n");
    sendData(&ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n");
    sendData(&ConnectSocket, "\r\n\r\n");

    FILE* MailFilePtr = fopen("details.txt", "r");
    if (MailFilePtr == NULL)
        printf("Error opening attachment\n");

    char FileBuffer[1024];
    char buf[1024];

    memset(FileBuffer, 0, sizeof(FileBuffer));
    while (fgets(FileBuffer, sizeof(FileBuffer), MailFilePtr))
    {
        sprintf(buf, "%s", FileBuffer);
        buf[strlen(buf) - 1] = 0;
        sendData(&ConnectSocket, buf);
        memset(FileBuffer, 0, sizeof(FileBuffer));
        memset(buf, 0, sizeof(buf));
    }

    fclose(MailFilePtr);

    sendData(&ConnectSocket, "\r\n\r\n--KkK170891tpbkKk__FV_KKKkkkjjwq--\r\n\r\n");
    sendData(&ConnectSocket, ".\r\n");
    recvData(&ConnectSocket);

    sendData(&ConnectSocket, "QUIT\r\n");

    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    closesocket(ConnectSocket);
    WSACleanup();
    return 0;
}
\ifndef WIN32\u LEAN\u和\u MEAN
#定义WIN32_精益_和_平均值
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#pragma注释(lib,“Ws2_32.lib”)
#定义SMTP_端口“25”
#定义默认值\u BUFLEN 1024
int sendData(套接字*套接字,常量字符*数据)
{
国际结果;
printf(“%s”,数据);
iResult=send(*套接字,数据,(int)strlen(数据),0);
if(iResult==SOCKET\u错误){
printf(“发送失败(消息:%s):%d\n”,数据,WSAGetLastError());
}
返回iResult;
}
void recvData(套接字*套接字)
{
int recvbuflen=默认值;
char recvbuf[默认值];
国际结果;
iResult=recv(*套接字,recvbuf,recvbuflen-1,0);
printf(“在recvData函数中:%d\n”,iResult);
如果(iResult>0){
recvbuf[iResult]='\0';
printf(“%s”,recvbuf);
}
else if(iResult==0)
printf(“连接关闭\n”);
其他的
printf(“recv失败:%d\n”,WSAGetLastError());
}
int main(int argc,字符**argv)
{
WSADATA WSADATA;
国际结果;
iResult=WSAStartup(MAKEWORD(2,2)和wsaData);
如果(iResult!=0){
printf(“WSAStartup失败:%d\n”,iResult);
返回1;
}
struct addrinfo*result=NULL;
struct addrinfo*ptr=NULL;
结构addrinfo提示;
零内存(&提示,sizeof(提示));
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
hits.ai_protocol=IPPROTO_TCP;
iResult=getaddrinfo(“mail.sharklasers.com”、SMTP_端口、提示和结果);
如果(iResult!=0){
printf(“getaddrinfo失败:%d\n”,iResult);
WSACleanup();
返回1;
}
SOCKET ConnectSocket=无效的_套接字;
for(ptr=result;ptr!=NULL;ptr=ptr->ai_next){
ConnectSocket=socket(ptr->ai_系列,ptr->ai_socktype,ptr->ai_协议);
if(ConnectSocket==无效的_套接字){
printf(“套接字失败:%ld\n”,WSAGetLastError());
WSACleanup();
返回1;
}
iResult=connect(ConnectSocket,ptr->ai_addr,(int)ptr->ai_addrlen);
if(iResult==SOCKET\u错误){
闭合插座(连接插座);
ConnectSocket=无效的_套接字;
继续;
}
打破
}
freeaddrinfo(结果);
if(ConnectSocket==无效的_套接字){
printf(“无法连接到服务器!\n”);
WSACleanup();
返回1;
}
sendData(&ConnectSocket,“HELO mail.sharklasers.com\r\n”);
recvData(&ConnectSocket);
sendData(&ConnectSocket),“邮件发件人:psgibrxp@sharklasers.com\r\n”);
recvData(&ConnectSocket);
发送数据(&ConnectSocket),将RCPT发送到:psgibrxp@sharklasers.com\r\n”);
recvData(&ConnectSocket);
sendData(&ConnectSocket,“数据\r\n”);
recvData(&ConnectSocket);
sendData(&ConnectSocket,“主题:这是我的邮件的主题\r\n”);
sendData(&ConnectSocket,“这是文本\r\n”);
sendData(&ConnectSocket,“MIME版本:1.0\r\n”);
sendData(&ConnectSocket,“内容类型:多部分/混合;边界=\”KKK170891TPKKK\uu FV\u KKKKJJWQ\”\r\n”);
sendData(&ConnectSocket,“--KKK170891TPKKK_uufv_KKKKJJWQ\r\n”);
sendData(&ConnectSocket,“内容传输编码:带引号的可打印\r\n”);
sendData(&ConnectSocket,“内容类型:text/plain;name=\”details.txt\“\r\n”);
sendData(&ConnectSocket,“内容处置:附件;文件名=\”details.txt\“\r\n”);
sendData(&ConnectSocket,“\r\n\r\n”);
FILE*MailFilePtr=fopen(“details.txt”,“r”);
if(MailFilePtr==NULL)
printf(“打开附件时出错”);
char文件缓冲区[1024];
char-buf[1024];
memset(FileBuffer,0,sizeof(FileBuffer));
而(fgets(FileBuffer、sizeof(FileBuffer)、MailFilePtr))
{
sprintf(buf,“%s”,文件缓冲区);
buf[strlen(buf)-1]=0;
sendData(&ConnectSocket,buf);
memset(FileBuffer,0,sizeof(FileBuffer));
memset(buf,0,sizeof(buf));
}
fclose(MailFilePtr);
sendData(&ConnectSocket),“\r\n\r\n--KKK170891TPKKKK__FV_KKKKKJJWQ--\r\n\r\n”);
sendData(&ConnectSocket“”。\r\n“;
recvData(&ConnectSocket);
sendData(&ConnectSocket,“退出\r\n”);
iResult=关机(ConnectSocket,SD_发送);
if(iResult==SOCKET\u错误){
printf(“关闭失败:%d\n”,WSAGetLastError());
闭合插座(连接插座);
WSACleanup();
返回1;
}
闭合插座(连接插座);
WSACleanup();
返回0;
}
问题: 如何获得正确格式的邮件正文?我想我丢失了一些SMTP命令或命令序列,但我不确定

注意

  • 我现在正在使用Guerrilla邮件,因为Gmail需要SSL\TLS进行通信(如果我错了,请纠正我)。为此,我将使用openssl库
  • 这不是最终的代码。我确实需要做一些代码清理。然而,代码审查建议也是受欢迎的
  • 我在这里学习,所以欢迎任何与C语言和网络编程相关的链接、参考书
  • 编辑

    编辑的代码基于到目前为止的注释和答案。不幸的是,这个问题仍然存在。 我没有读取文件,而是直接传递base64编码的附件(这是有效的)。下面的屏幕截图显示了此编辑代码的输出

        sendData(&ConnectSocket, "MIME-Version: 1.0\r\n");
        sendData(&ConnectSocket, "Content-Type:multipart/mixed;boundary=\"977d81ff9d852ab2a0cad646f8058349\"\r\n");
        sendData(&ConnectSocket, "Subject:This is subject of my mail\r\n");
        sendData(&ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
        sendData(&ConnectSocket, "Content-Type: text/plain; charset=\"utf-8\"\r\n");
        sendData(&ConnectSocket, "Content-Transfer-Encoding: quoted-printable\r\n\r\n");
        sendData(&ConnectSocket, "Hi Me,=0A=0AThis is an empty file.=0A=0ARegards,=0A<ME>=0A=0A---- =0ASent using Guerrillamail.com =0ABlock or report abuse : https://www.guerrillamail.com//abuse/?a=3DUVJzDA8SW6Q1mwa14nUTcwfCX9ne0dhd=0A \r\n\r\n");
        sendData(&ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
        sendData(&ConnectSocket, "Content-Type: text/plain\r\n");
        sendData(&ConnectSocket, "Content-Transfer-Encoding: base64\r\n");
        sendData(&ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n\r\n");
        sendData(&ConnectSocket, "U2FtcGxlIFRleHQu");
        sendData(&ConnectSocket, "\r\n\r\n--977d81ff9d852ab2a0cad646f8058349--\r\n\r\n");
        sendData(&ConnectSocket, ".\r\n");
        recvData(&ConnectSocket);
        sendData(&ConnectSocket, "QUIT\r\n");
    
    sendData(&ConnectSocket,“MIME版本:1.0\r\n”);
    sendData(&ConnectSocket,“内容类型:多部分/混合;边界=\”977d81ff9d852ab2a0cad646f8058349\“\r\n”);
    sendData(&ConnectSocket,“主题:这是我的邮件的主题\r\n”);
    sendData(&ConnectSocket),“--977d81ff
    
    sendData(&ConnectSocket, "Content-Type: text/plain");
    
    sendData(&ConnectSocket, "MIME-Version: 1.0\r\n");
    sendData(&ConnectSocket, "Content-Type:multipart/mixed;boundary=\"KkK170891tpbkKk__FV_KKKkkkjjwq\"\r\n");
    sendData(&ConnectSocket, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n");
    sendData(&ConnectSocket, "Content-Type: text/plain\r\n");
    sendData(&ConnectSocket, "And this is text\r\n");
    sendData(&ConnectSocket, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n");
    sendData(&ConnectSocket, "Content-Type: text/plain;name=\"details.txt\"\r\n");
    sendData(&ConnectSocket, "Content-Transfer-Encoding: base64\r\n");
    sendData(&ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n");
    
    sendData(&ConnectSocket, "MIME-Version: 1.0\r\n");
    sendData(&ConnectSocket, "Content-Type:multipart/mixed;boundary=\"977d81ff9d852ab2a0cad646f8058349\"\r\n");
    sendData(&ConnectSocket, "Subject:This is subject of my mail\r\n");
    sendData(%ConnectSocket, "\r\n"); /* added */
    sendData(&ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
    sendData(&ConnectSocket, "Content-Type: text/plain; charset=\"utf-8\"\r\n");
    sendData(&ConnectSocket, "Content-Transfer-Encoding: quoted-printable\r\n\r\n");
    sendData(&ConnectSocket, "Hi Me,=0A=0AThis is an empty file.=0A=0ARegards,=0A<ME>=0A=0A---- =0ASent using Guerrillamail.com =0ABlock or report abuse : https://www.guerrillamail.com//abuse/?a=3DUVJzDA8SW6Q1mwa14nUTcwfCX9ne0dhd=0A \r\n\r\n");
    sendData(&ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
    sendData(&ConnectSocket, "Content-Type: text/plain\r\n");
    sendData(&ConnectSocket, "Content-Transfer-Encoding: base64\r\n");
    sendData(&ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n\r\n");
    sendData(&ConnectSocket, "U2FtcGxlIFRleHQu");
    sendData(&ConnectSocket, "\r\n\r\n--977d81ff9d852ab2a0cad646f8058349--\r\n\r\n");
    sendData(&ConnectSocket, ".\r\n");