接收 SMTP 消息
Receiving an SMTP message
我正在尝试实现 SMTP 服务器。
问题是在我的套接字 accept
建立新连接后,它没有接收到任何字节(示例输出中的空白行),因此我的 read
循环终止。
我尝试在初始 accept
之后发送 220
和 250
命令,但仍然没有成功。
我的输出:
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;
}
您正在从错误的套接字读取。 accept
returns 您应该从中读取的套接字,即 input_sockfd
。您正在从传递给未连接到客户端的 accept
的套接字中读取,因此 read
正确地 returns 0 个字节。
您在支票n < 0
中也有一个off-by-one。 read
returns 0 当连接关闭时,所以你真的应该检查 n <= 0
,否则循环将永远继续下去,总是读取 0 个字节。
我正在尝试实现 SMTP 服务器。
问题是在我的套接字 accept
建立新连接后,它没有接收到任何字节(示例输出中的空白行),因此我的 read
循环终止。
我尝试在初始 accept
之后发送 220
和 250
命令,但仍然没有成功。
我的输出:
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;
}
您正在从错误的套接字读取。 accept
returns 您应该从中读取的套接字,即 input_sockfd
。您正在从传递给未连接到客户端的 accept
的套接字中读取,因此 read
正确地 returns 0 个字节。
您在支票n < 0
中也有一个off-by-one。 read
returns 0 当连接关闭时,所以你真的应该检查 n <= 0
,否则循环将永远继续下去,总是读取 0 个字节。