我正在为学校项目编写简单的FTP服务器,我遇到文件传输问题。
实际上,当发送命令PASV时,我创建一个带有指定端口的套接字并监听但后来当发送命令RETR并且我尝试在套接字文件描述符上写入文件时,写块阻止执行该程序和ftp客户端一直在等待。
为什么这个写阻塞?
此功能创建我的套接字
int create_s_socket(struct sockaddr_in *sock, int port)
{
int socket_fd;
int enable;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
return (-1);
enable = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
return (-1);
sock->sin_family = AF_INET;
sock->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sock->sin_port = htons(port);
if (bind(socket_fd, (struct sockaddr *)sock, sizeof(*sock)) < 0)
return (-1);
return (socket_fd);
}
此功能打开数据连接(被动模式)
void cmd_pasv(t_handle *hdl)
{
struct sockaddr_in data_sock;
uint16_t port;
socklen_t len;
len = sizeof(data_sock);
if ((hdl->data_fd = create_s_socket(&data_sock, 0)) != -1)
{
listen(hdl->data_fd, 5);
getsockname(hdl->data_fd, (struct sockaddr *)&data_sock, &len);
port = ntohs(data_sock.sin_port);
printf("port = %d\n", port);
set_rep(hdl, 227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d).",
(int)(data_sock.sin_addr.s_addr & 0xFF),
(int)((data_sock.sin_addr.s_addr & 0xFF00) >> 8),
(int)((data_sock.sin_addr.s_addr & 0xFF0000) >> 16),
(int)((data_sock.sin_addr.s_addr & 0xFF000000) >> 24),
(int)(port / 256), (int)(port % 256));
printf("data fd %d\n", hdl->data_fd);
}
else
set_rep(hdl, 500, "Canno open data connection");
}
此功能打开广告通过数据线发送文件
void cmd_retr(t_handle *hdl)
{
char *fullpath;
FILE *file;
size_t nread;
char buf[BLOCK_SIZE];
log_msg(INFO, "data fd is %d", hdl->data_fd);
if (hdl->data_fd > 0)
{
log_msg(INFO, "data fd is %d", hdl->data_fd);
if (hdl->cmd_arg)
{
log_msg(INFO, "file to uploadis %s", hdl->cmd_arg);
fullpath = malloc(sizeof(char) *
strlen(hdl->path) + strlen(hdl->cmd_arg) + 2);
sprintf(fullpath, "%s/%s", hdl->path, hdl->cmd_arg);
log_msg(INFO, "full path is %s", fullpath);
if ((file = fopen(fullpath, "r")) != NULL)
{
log_msg(INFO, "file opened correctly");
while ((nread = fread(buf, sizeof(char), BLOCK_SIZE, file)) > 0)
{
log_msg(INFO, "read %d bytes \"%s\"", nread, buf);
if (write(hdl->data_fd, buf, nread) == -1)
log_msg(ERROR, "write: %s", strerror(errno));
}
if (nread < 0)
log_msg(ERROR, "read: %s", strerror(errno));
}
else
set_rep(hdl, 000, "File \"%s\" not found", fullpath);
free(fullpath);
}
else
set_rep(hdl, 000, "Missing arg");
}
else
set_rep(hdl, 000, "Data connection not open fd %d", hdl->data_fd);
}
谢谢;)
答案 0 :(得分:1)
实际上,当发送命令PASV时,我创建一个带有的套接字 指定端口和监听,但稍后在发送命令RETR时 我尝试在socket文件描述符上写入文件 阻止程序的执行,ftp客户端一直在等待。
为什么这个写阻塞?
目前还不清楚您是否提供了所有相关代码。如果你有,那么问题肯定是你试图写入服务器套接字。您应该accept()
与该套接字建立连接,验证它是否来自预期的客户端,并使用生成的连接的套接字(具有不同的文件描述符)进行通信。