Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.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
SMTP C++;linux使用套接字如何实现SSL? 我在Linux套接字中有C++的SMTP.CPP程序的问题。 我必须输入以下(域)account@domain recipient@domain附件和准备邮件),填写后,smtp应发送电子邮件至 recipient@domain但它一直在说信息没有被发送。 smtp没有ssl,因为我只想使用port25发送电子邮件和测试。 但是我不能在端口25上使用它,我需要在套接字上实现SSL(端口465)。有人知道如何实现这一点,以便smtp工作吗? 请帮忙_C++_Linux_Sockets_Smtp - Fatal编程技术网

SMTP C++;linux使用套接字如何实现SSL? 我在Linux套接字中有C++的SMTP.CPP程序的问题。 我必须输入以下(域)account@domain recipient@domain附件和准备邮件),填写后,smtp应发送电子邮件至 recipient@domain但它一直在说信息没有被发送。 smtp没有ssl,因为我只想使用port25发送电子邮件和测试。 但是我不能在端口25上使用它,我需要在套接字上实现SSL(端口465)。有人知道如何实现这一点,以便smtp工作吗? 请帮忙

SMTP C++;linux使用套接字如何实现SSL? 我在Linux套接字中有C++的SMTP.CPP程序的问题。 我必须输入以下(域)account@domain recipient@domain附件和准备邮件),填写后,smtp应发送电子邮件至 recipient@domain但它一直在说信息没有被发送。 smtp没有ssl,因为我只想使用port25发送电子邮件和测试。 但是我不能在端口25上使用它,我需要在套接字上实现SSL(端口465)。有人知道如何实现这一点,以便smtp工作吗? 请帮忙,c++,linux,sockets,smtp,C++,Linux,Sockets,Smtp,smtp.cpp #include <cstdio> #include <cstdlib> #include <cstring> #include <set> #include <string> #include <iostream> #include <ctime> #include <fstream> #include <errno.h> #include <netdb.h>

smtp.cpp

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <string>
#include <iostream>
#include <ctime>
#include <fstream>
#include <errno.h>
#include <netdb.h>//s_port , h_name,h_addrtype
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sstream>
#include <vector>

using namespace std;


#define buf_size 1024
#define chunk_size 54 //rozmiar porcji
void err(const char *where) 
{
    fprintf(stderr, "error in %s: %d\n", where, errno);
    exit(1);
}
string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

string BOUNDARY_TEXT = "BOUNDARY_TEXT";
string CRLF = "\r\n";//CR, wartość ASCII równa 13, '\r') + line feed (LF, wartość ASCII 10, '\n'
// OZNACZA koniec bieżącej linii

string getFormatTime()
{
    time_t rawtime;
    struct tm * timeinfo;
    char bufer[80];

    time (&rawtime);
    timeinfo = localtime (&rawtime);

    strftime (bufer, 80, "Date: %a, %d %B %Y %T %z", timeinfo);//Format time as string
    string time(bufer);
    return time;
}

string getHeader(string login, string recipient, string subject, vector<string> &attachments)
{
    stringstream header;
    // Date: <SP> <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <zone> <CRLF>
    header << getFormatTime() << CRLF;
    // From: <SP> <sender>  <SP> "<" <sender-email> ">" <CRLF>
    header << "From: <" << login << ">" << CRLF;
    // X-Mailer: <SP> <xmailer-app> <CRLF>
    header << "X-Mailer: Poster" << CRLF;
    // Reply-To: <SP> <reverse-path> <CRLF>
    // X-Priority: <SP> <number> <CRLF>
    header << "X-Priority: 3 (Normal)" << CRLF;
    // To: <SP> <remote-user-mail> <CRLF>
    header << "To: <" << recipient << ">" << CRLF;
    // Cc: <SP> <remote-user-mail> <CRLF>
    // Bcc: <SP> <remote-user-mail> <CRLF>
    // Subject: <SP> <subject-text> <CRLF>
    header << "Subject: " << subject << CRLF;
    // MIME-Version: <SP> 1.0 <CRLF>
    header << "MIME-Version: 1.0" << CRLF;

    if(attachments.size() == 0)
    {
     //Content-Type POLE TYPU ZAWARTOŚCI
       // uzywane jest do wskazania klientowi poczty zarówno uzytego sposobu kodowania 
       //wiadomosci, jak i ewentualnie sposobu postepowania z odebrana wiadomoscia.
        header << "Content-type: text/plain; charset=US-ASCII" << CRLF;
        //Content-Transfer-Encoding informuje, w jaki sposob traktuje sie znaki o kodach wiekszych od 127
        header << "Content-Transfer-Encoding: 7bit" << CRLF;
        header << CRLF;
    }
    else
    {
    //wiadomosc zawiera kilka rozlacznych czesci 
  //Tekst w 'boundary' bedzie wykorzystywany jako znacznik rozdzielajacy kazdy ze skladnikow wiadomosci
        header << "Content-Type: multipart/mixed; boundary=\"";
        header << BOUNDARY_TEXT << "\"" << CRLF;
        header << "--" << BOUNDARY_TEXT << CRLF;
        header << "Content-type: text/plain; charset=US-ASCII" << CRLF;
        header << "Content-Transfer-Encoding: 7bit" << CRLF;
        header << CRLF;
    }
    return header.str();
}
//kodowanie wiadomosci
string encode(char* chunk, int length)
{
    string ostr = "";
    static long long out_size = 0;

    for(int i = 0; i < length; i+=3)
    {
        unsigned char s1 = chunk[i];
        //Gott!!! FIXED
        unsigned char s2 = (length > 1) ? chunk[i+1] : 0;
        unsigned char s3 = (length > 2) ? chunk[i+2] : 0;

        int n = s1;
        n <<= 8;
        n |= s2;
        n <<= 8;
        n |= s3;

        int p1 = static_cast<int>(n & 0x3f);
        n >>= 6;
        int p2 = static_cast<int>(n & 0x3f);
        n >>= 6;
        int p3 = static_cast<int>(n & 0x3f);
        n >>= 6;
        int p4 = static_cast<int>(n & 0x3f);

        ostr += base64_chars[p4];
        ostr += base64_chars[p3];

        if(length - i >= 3)
        {
            ostr += base64_chars[p2];
            ostr += base64_chars[p1];
        }
        if(length - i == 2)
        {
            ostr += base64_chars[p2];
            ostr += '=';
        }
        if(length - i == 1)
        {
            ostr += '=';
            ostr += '=';
        }

        out_size += 4;
    }
    return ostr;
}
/*
Funkcja getline jest preferowana metoda czytania linii tekstu z gniazda, 
w tym standardowych wejscia.Pobiera linie danych z gniazda socket
*/
static int getLine (int socket, char *line, int length)
{
    //memset(line, '\0', buf_size);
    char ch;
    int bytes = 0;

    while (read(socket, &ch, 1) > 0)
    {
        *line++ = ch;
        bytes++;
        if (ch == '\n')
        {
            *line = 0;
            return bytes;
        }

        if (bytes == length - 1)
        {
            *line = 0;
            return bytes;
        }
    }
    *line = 0;
    err("problem");
    return -1;
}
//wysylanie
void send(int sock, string command)
{
    write(sock, command.c_str(), command.length());
}
//odbior
int receive(int sock)
{
    char buf[buf_size];
    char code[3];
    getLine(sock, buf, buf_size);
    strncpy(code, buf, 3);
    puts(buf);
    return atoi(code);;//Convert string to integer
}
//wysyla plik
void sendFile(int sock, string file_to_send)
{
    //ifstream - Stream class to read from files
    //Construct object and optionally open file
    ifstream is(file_to_send.c_str(), ifstream::binary);
    string out = "";

    if (is) 
    {
        is.seekg(0, is.end);//Set position in input sequence
        is.seekg(0, is.beg);

        char chunk[chunk_size];
        while(!is.eof())
        {
            is.read(chunk, chunk_size);
            send(sock, encode(chunk, is.gcount()) + CRLF);
        }
        is.close();
    }
}
//wysylanie maila
int sendMail(int sock, char* account_login, char* passwd, string recipient, string subject, string msg, vector<string> &attachments)
{
    string header;

    send(sock, "helo domain" + CRLF);
    if(receive(sock) != 250)
    err("domain problem");
        return -1;

    send(sock, "auth login" + CRLF);
    if(receive(sock) != 334)
    err("auth login problem");
        return -2;
    //zakodowany login
    send(sock, encode(account_login, strlen(account_login)) + CRLF); 
    if(receive(sock) != 334)
    err("encoding login problem");
        return -3;

    send(sock, encode(passwd, strlen(passwd)) + CRLF);
    if(receive(sock) != 235)
    err("encoding password problem");
        return -4;

    string login(account_login);
    send(sock, "mail from:" + login + CRLF);
    if(receive(sock) != 250)
    err("account-domain problem");
        return -5;

    send(sock, "rcpt to:" + recipient + CRLF);
    if(receive(sock) != 250)
    err("recipient problem");
        return -6;

    send(sock, "data" + CRLF);
    if(receive(sock) != 354)
    err("data problem");
        return -7;

    header = getHeader(login, recipient, subject, attachments);
    send(sock, header);

    if(msg.size() == 0)
        send(sock, " " + CRLF);
    else
        send(sock, msg + CRLF);

    vector<string>::iterator temp = attachments.begin();
    while(++temp != attachments.end())
    {
        stringstream ss;
        ss << "--" << BOUNDARY_TEXT <<
        ss << "Content-Type: application/x-msdownload; name=\"";
        ss << basename(static_cast<string>(*temp).c_str());
        ss << "\"" << CRLF;
        //sposob kodowania informacji binarnej
        ss << "Content-Transfer-Encoding: base64" << CRLF;
        //pole Content-Disposition identyfikuje te czesc wiadomosci jako załacznik
        ss << "Content-Disposition: attachment; filename=\"";
        ss << basename(static_cast<string>(*temp).c_str());
        ss << "\"" << CRLF;
        ss << CRLF;
        send(sock, ss.str());
        cout << *temp << endl;

        sendFile(sock, *temp);
    }

    if(attachments.size() > 0)
    {
        send(sock, CRLF);
        send(sock, "--" + BOUNDARY_TEXT + "--" + CRLF);
    }
//Klient musi poprawnie obsługiwać pojawienie się linii wiadomości 
//zaczynającej się od kropki lub kropek.
    // <CRLF> . <CRLF>
    send(sock, CRLF + "." + CRLF);
    if(receive(sock) != 250)
    err(". problem");
        return -8;

    send(sock, "quit" + CRLF);
    if(receive(sock) != 250)
    err("quit problem");
        return -9;
    return 0;
}
/*
void err(const char *where) 
{
    fprintf(stderr, "error in %s: %d\n", where, errno);
    exit(1);
}
*/
int connect(char* server, const char* proto)
{
    //adres serwera np poczta.o2.pl
    char *remote = server; 
    //struktura zwiazana z serwerem
    struct servent *sent;
    //struktura zwiazana z nazwa protokolu
    struct protoent *pent;
    int  port;
    int  sock;
    int  result;
    //struct in_addr {in_addr_t s_addr lub ipadr;};
    in_addr_t ipadr;
    //struktura obslugujaca adresowe internetowe
    struct sockaddr_in addr;
    //struktura zwiazana z nazwa hosta
    struct hostent *hent;

    char buf[buf_size];
    char filename[30];
     //łańcuch zawierający nazwę usługi (np. ”pop3”,"http" itp)
   //łańcuch zawierający nazwę protokołu (”tcp”, ”udp”, ”ip”)
    sent = getservbyname(proto, "tcp");
    if(sent == NULL)
        err("getservbyname");
    port = sent->s_port;
    pent = getprotobyname("tcp");
    if(pent == NULL)
        err("getprotobyname");
        //nazwa hosta w postaci łańcucha (symboliczna lub adres IP)
    hent = gethostbyname(remote);
    printf("Host: %s\n", hent->h_name);
    printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hent->h_addr)));
    //struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr = *((struct in_addr *)hent->h_addr);
    //Sets the first 8 bytes of the block of memory pointed by sin_zero to the specified value \0
    memset(addr.sin_zero, '\0', 8);
    //AF_INET - internet domain sockets|SOCK_STREAM - Byte-stream socket,
    sock = socket(AF_INET, SOCK_STREAM, pent->p_proto);
    if(sock < 0)
        err("socket");
    result = connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if(result < 0)
        err("connect");

    getLine(sock, buf, buf_size);
    puts(buf);

    return sock;
}

int main(int argc, char* argv[])
{
    if(argc < 4)
    {
        cout << "usage: " << argv[0] << ": domain account@domain recipient@domain [attachment, attachment, ...]" << endl;
        return 0;
    }

    char* server = argv[1];
    char* account_login = argv[2];
    string recipient(argv[3]);
    string subject = "";
    string msg = "";
    vector<string> attachments;

    for(int i = 3; i < argc; i++)
    {
        string filename(argv[i]);
        attachments.push_back(filename);
    }

    cout << "Preparing message..." << endl << endl;
    cout << "Enter your topic: " << endl;
    getline(cin, subject);
    cout << "Enter your message here <EOF>" << endl;

    char tempChar;
    while (!cin.eof())
    {
        cin.get(tempChar);
        msg += tempChar;
    }
    //getpass - ukrywa nam haslo podczas wprowadzania go na ekranie
    char* passwd = (char*)(intptr_t)getpass("Enter password: ");

    int sock = connect(server, "smtp");
    if(sendMail(sock, account_login, passwd, recipient, subject, msg, attachments) != 0)
        cout`enter code here` << "Message not sent." << endl;
    else
        cout << "Message has been sent successfully." << endl;

    close(sock);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括//s\U端口、h\U名称、h\U地址类型
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#定义buf_大小1024
#定义块大小54//rozmiar porcji
无效错误(常量字符*其中)
{
fprintf(标准,“%s中的错误:%d\n”,其中,errno);
出口(1);
}
字符串base64_chars=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyzo123456789+/”;
字符串BOUNDARY\u TEXT=“BOUNDARY\u TEXT”;
字符串CRLF=“\r\n”//CR,wartośćASCII równa 13,'\r')+换行符(LF,wartośćASCII 10,'\n'
//奥兹纳扎·科尼奇·比埃切伊·利尼
字符串getFormatTime()
{
时间与时间;
结构tm*时间信息;
char-bufer[80];
时间(&rawtime);
timeinfo=localtime(&rawtime);
strftime(bufer,80,“日期:%a,%d%B%Y%T%z”,timeinfo);//将时间格式化为字符串
字符串时间(bufer);
返回时间;
}
string getHeader(字符串登录、字符串收件人、字符串主题、向量和附件)
{
串流头;
//日期::“”

头允许
sendMail()
为几十个不同的错误返回相同的错误代码,并且根本不打印任何错误消息,这对调试非常没有帮助。修复
sendMail()
相应地。之后,您将知道它在哪里中断以及可能中断的原因。类似的问题也适用于您的其他函数。在很多地方,您只需忽略返回代码。也可以解决此问题。查看
errno
将有助于../smtp poczta.o2.plkalamata1991@o2.pl erotas@amorki.pllol.txt正在准备消息…E输入你的主题:fgffg在这里输入你的消息gfgfgf ssfs输入密码:Host:poczta.o2.pl IP:193.17.41.99 220 poczta.o2.pl ESMTP Wita 250 poczta.o2.pl域错误问题:0我肯定写了正确的域。我不知道为什么会出现错误使用像…这样的库并使用
g++-Wall-g
编译,然后使用调试器(
gdb
)我只能使用套接字提供的库和类。我不能使用其他库或类,因为错误发生在
receive()
?在这种情况下,请检查服务器返回了什么(可能是错误消息?)以及发生了什么错误代码。此外,我不会调用
getline()
在套接字上,使用
read()
并检查其返回代码。