SMTP-клиент C ++ не отвечает после подключения к серверу - PullRequest
0 голосов
/ 11 апреля 2020

Я пытаюсь создать SMTP-клиент для отправки электронной почты, но не могу подключиться к smtp.gmail.com. Само соединение, похоже, не дает сбоя, но recv блокирует, не выдавая приветственного сообщения. Работает как положено, когда я использую Te lnet.

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

    iResult = getaddrinfo("smtp.gmail.com", "465", &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    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 with error: %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;
    }


    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);

    std::cout << recvbuf << std::endl;

1 Ответ

0 голосов
/ 11 апреля 2020

Порт 465 использует неявный TLS, который требует от клиента согласования сеанса TLS сразу после подключения, прежде чем он сможет затем прочитать (зашифрованное) приветственное сообщение сервера. Вы ничего не получаете, потому что сервер еще ничего не отправляет. Он ожидает, что вы отправите подтверждение TLS, чего вы не делаете.

Существует также концепция явного TLS на портах 25 и 587, где клиент должен прочитать (незашифрованное) приветственное сообщение, а затем отправьте команду STARTTLS перед началом сеанса TLS.

...