【问题标题】:Receiving an SMTP message接收 SMTP 消息
【发布时间】:2019-10-30 16:44:21
【问题描述】:

我正在尝试实现一个 SMTP 服务器。
问题是在我的套接字accepts 一个新连接之后,它没有收到任何字节(示例输出中的空白行),因此我的read 循环被终止。

我尝试在最初的accept 之后发送220250 命令,但仍然没有成功。


我的输出:

Socket created
Waiting for incoming connections...
Connection accepted
250 mail.domain.com says hello

Finished reading current message

我的代码:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define MAX_CONNECTIONS 10
#define BUF_SIZE        2000
#define STREQU(a,b)     (strcmp(a, b) == 0)

void init_local_sockaddr_in(struct sockaddr_in *sock, int portnum) {
    sock->sin_family = AF_INET;
    sock->sin_addr.s_addr = inet_addr("127.0.0.1");
    sock->sin_port = htons(portnum);
}

int main(int argc, char *argv[])
{
    int listen_sockfd, input_sockfd, c, read_size, n;
    struct sockaddr_in server, client;
    char client_message[2000] = {0};
    char bufferout[2000] = {0};

    listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sockfd == -1) {
        printf("Could not create sockets");
    }
    puts("Socket created");

    // Just for better debugging
    int optval = 1;
    setsockopt(listen_sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));

    init_local_sockaddr_in(&server, 10025);
    n = bind(listen_sockfd, (struct sockaddr*) &server, sizeof(server));
    if (n < 0) {
        perror("bind failed. Error");
        return 1;
    }

    listen(listen_sockfd , MAX_CONNECTIONS);

    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    while(1) {
        input_sockfd = accept(listen_sockfd, (struct sockaddr*) &client, (socklen_t*) &c);
        if (input_sockfd < 0) {
            perror("accept failed");
            return 1;
        }
        puts("Connection accepted");

        sprintf(bufferout, "250 mail.domain.com says hello\r\n"); // I tried different replies here, including 220
        send(input_sockfd, bufferout, strlen(bufferout), 0);
        puts(bufferout);

        int keep_running = 1;

        while (keep_running) {
            n = read(listen_sockfd, client_message, sizeof(client_message));
            if (STREQU(client_message, ".") || n < 0) {
                keep_running = 0;
                break;
            }
            printf("Read %lu bytes: %s\n", strlen(client_message), client_message);
            memset(client_message, 0, sizeof(client_message));
        }
        close(input_sockfd);
        puts("Finished reading current message");
    }
    close(listen_sockfd);

    return 0;
}

【问题讨论】:

  • @kiranBiradar 抱歉,我尝试简化我的代码,但没有注意到这个缓冲区。一旦收到邮件,整个过程就开始了

标签: c smtp postfix-mta


【解决方案1】:

您从错误的套接字读取。 accept 返回您应该从中读取的套接字,即input_sockfd。您正在从传递给accept 的套接字中读取数据,该套接字未连接到客户端,因此read 正确返回 0 个字节。

您的支票n &lt; 0 中也有一个一号位。 read 在连接关闭时返回 0,所以你真的应该检查 n &lt;= 0,否则循环将永远持续下去,总是读取 0 字节。

【讨论】:

  • 天啊,大获成功!我不相信这最终是问题所在。我坐在这个变体上超过两天,对时间的长短感到困惑。非常感谢!
  • @GalAbra 为答案添加了第二个错误修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多