实现 FTP 服务器"LIST"的问题



我正在实现FTP服务器,这里将winscp作为客户端。当客户端向我(服务器(发送PASV命令时,我将用ip地址和端口回复客户端,然后客户端发送LIST命令,然后我以的形式回复客户端

150 Opening ASCII mode data connection for file list
-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out
226 File transfer completed...

我在第二个端口发送这些响应。

像这样,但winscp总是显示";8检索目录表**失败";

但如果我在winscp的日志中看到我发送给客户端的数据不存在

你可以看到日志。。。。

. 2020-09-17 16:02:54.408 Username prompt (no username provided)
. 2020-09-17 16:03:00.663 Connecting to 192.168.5.37:5005 ...
. 2020-09-17 16:03:00.663 Connected with 192.168.5.37:5005. Waiting for welcome message...
< 2020-09-17 16:03:00.663 220 Welcome to Alan's FTP site
> 2020-09-17 16:03:00.663 USER srihari
< 2020-09-17 16:03:00.663 331 Password required 
> 2020-09-17 16:03:04.064 PASS *****
< 2020-09-17 16:03:04.064 230 Public login sucessful 
> 2020-09-17 16:03:04.064 SYST
< 2020-09-17 16:03:04.064 215 AmigaOS 
> 2020-09-17 16:03:04.064 FEAT
< 2020-09-17 16:03:04.064 202 Command not implemented, superfluous at this site. 
. 2020-09-17 16:03:04.079 Connected
. 2020-09-17 16:03:04.079 --------------------------------------------------------------------------
. 2020-09-17 16:03:04.079 Using FTP protocol.
. 2020-09-17 16:03:04.079 Doing startup conversation with host.
> 2020-09-17 16:03:04.095 PWD
< 2020-09-17 16:03:04.095 257 "/home/elmpc-162/ftp_server" 
. 2020-09-17 16:03:04.095 Getting current directory name.
. 2020-09-17 16:03:04.142 Retrieving directory listing...
> 2020-09-17 16:03:04.142 TYPE A
< 2020-09-17 16:03:04.142 200 Switching to ASCII mode. 
> 2020-09-17 16:03:04.142 PASV
< 2020-09-17 16:03:04.142 227 Entering Passive Mode (192,168,5,37,23,112) 
> 2020-09-17 16:03:04.142 LIST -a
. 2020-09-17 16:03:04.142 Connecting to 192.168.5.37:6000 ...
. 2020-09-17 16:03:19.757 Timeout detected. (data connection)

但在服务器中,它显示客户端已连接。

在这里我无法找出,为什么LIST的响应没有进行

有人能帮我吗

这是我的代码

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> //Header file for sleep(). man 3 sleep for details. 
#include <pthread.h> 
#include <stdio.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#define MAX 80 
#define PORT1 5013
#define PORT2 6004
#define SA struct sockaddr 
#define SA struct sockaddr 
char read_buffer[200],write_buffer[200];
char check=0;
void call_second(void);
// A normal C function that is executed as a thread 
// when its name is specified in pthread_create() 
void *first_thread(void *vargp) 
{ 
printf("in first thread.....n");
int sockfd, connfd, len; 
struct sockaddr_in servaddr, cli; 
// socket create and verification 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd == -1) { 
printf("socket creation failed...n"); 
exit(0); 
} 
else
printf("Socket successfully created..n"); 
bzero(&servaddr, sizeof(servaddr)); 
// assign IP, PORT 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port = htons(PORT1); 
// Binding newly created socket to given IP and verification 
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { 
printf("socket bind failed...n"); 
exit(0); 
} 
else
printf("Socket successfully binded..n"); 
// Now server is ready to listen and verification 
if ((listen(sockfd, 5)) != 0) { 
printf("Listen failed...n"); 
exit(0); 
} 
else
printf("Server listening..n"); 
len = sizeof(cli); 
// Accept the data packet from client and verification 
connfd = accept(sockfd, (SA*)&cli, &len); 
if (connfd < 0) { 
printf("server acccept failed...n"); 
exit(0); 
} 
else
printf("server acccept the client...n"); 
//bzero(buffer, 0); 
// sprintf(buffer,"n220 Welcome to Alan's FTP site rnn");

//for (;;) 
//write(sockfd, "welcome", sizeof("welcome")); 
// Function for chatting between client and server 
//printf("after writing into sockbuffer ...n");
//func(connfd); 
int n,bytes; 
// infinite loop for chat 
for (;;) 
{ 

//bzero(buff, MAX); 
memset(read_buffer,0,200);
memset(write_buffer,0,200);
sprintf(write_buffer,"n220 Welcome to Alan's FTP siternn");
write(connfd, write_buffer, sizeof(write_buffer)); 
printf("come inside..n");
// read the message from client and copy it in buffer 
while(1)
{
//sleep(1);
memset(read_buffer,0,200);
memset(write_buffer,0,200);
//printf("before reading....n");
bytes=read(connfd, read_buffer, sizeof(read_buffer)); 
//printf("checking blocking or not..  %sn",read_buffer);
if(bytes>0)
{
printf("From client:%s%dn", read_buffer,bytes);
} 
// if(strstr(buff,"AUTH TLS")||strstr(buff,"AUTH SSL"))
// {
//  sprintf(buffer,"n502 Command not implementedrnn");
//  write(sockfd, buffer, sizeof(buffer)); 
// }
if (strstr(read_buffer,"USER"))
{
printf("Logging in n");
sprintf(write_buffer,"331 Password required rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strncmp(read_buffer,"PASS",4)==0)
{
printf("Typing password (anything will do... n");
sprintf(write_buffer,"230 Public login sucessful rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strncmp(read_buffer,"SYST",4)==0)
{
printf("215 AmigaOS n");
//sprintf(write_buffer,"215 AmigaOS rn");
sprintf(write_buffer,"215 UNIX emulated by FileZilla rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));
memset(write_buffer,0,sizeof(write_buffer));

}
if (strncmp(read_buffer,"CLNT",4)==0)
{
printf("200 Don't care n");
sprintf(write_buffer,"200 Don't care rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strncmp(read_buffer,"OPTS UTF8 ON",4)==0)
{
printf("202 UTF8 mode is always enabled. No need to send this command. n");
sprintf(write_buffer,"202 UTF8 mode is always enabled. No need to send this command. rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strncmp(read_buffer,"FEAT",4)==0)
{
printf("211-Features:  n");
sprintf(write_buffer,"211-Features: rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
sprintf(write_buffer,"MDTM rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"REST STREAM rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"MLST type*;size*;modify*; rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
// memset(write_buffer,0,sizeof(write_buffer));
// sprintf(write_buffer,"MLSD rn");
// bytes = write(connfd, write_buffer, sizeof(write_buffer));   
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"UTF8 rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"CLNT rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"MFMT rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"CLNT rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"EPSV rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"EPRT rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"211 End rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer));  
memset(write_buffer,0,sizeof(write_buffer));
printf("211 end:  n");

}
if (strncmp(read_buffer,"PWD",3)==0)
{
printf("present working directory n");
//  FILE *fpipe;
char pwd[100],i=5;
// char *command = "pwd";
// char c = 0;
// if (0 == (fpipe = (FILE*)popen(command, "r")))
// {
//  perror("popen() failed.");
//  exit(EXIT_FAILURE);
// }
// strcat(pwd,"257 "");
// printf("%sn",pwd);
// while (fread(&c, sizeof c, 1, fpipe))
// {
//  //printf("%c", c);
//  pwd[i++]=c;
// }
// strcat(pwd,"" rn");
memset(pwd,0,sizeof(pwd));
// strcat(pwd,"257 "/"rn");
strcat(pwd,"257 "/home/elmpc-162/ftp_server" ");
printf("%sn",pwd);
//pclose(fpipe);
// sprintf(write_buffer,"202 Command not implemented, superfluous at this site. rn");
bytes = write(connfd, pwd, sizeof(pwd)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"TYPE I"))
{
printf(" 200 Switching to Binary mode.n");
sprintf(write_buffer,"200 Switching to Binary mode. rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"TYPE A"))
{
printf(" 200 Switching to ASCII mode.n");
sprintf(write_buffer,"200 Switching to ASCII mode. rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"AUTH TLS"))
{
printf(" asking AUTHTLSn");
sprintf(write_buffer,"502 Explicit TLS authentication not allowed rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"AUTH SSL"))
{
printf(" asking AUTHTLSn");
sprintf(write_buffer,"502 Explicit TLS authentication not allowed rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"CDUP"))
{
printf(" got CDUP command n");
sprintf(write_buffer,"457 "/home" rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strstr(read_buffer,"CWD"))
{
printf(" got CWD command n");
sprintf(write_buffer,"457 "/home/elmpc-162/ftp_server" rn");
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;
}
if (strncmp(read_buffer,"PASV",4)==0)
{int a,b;
//close(sockfd);
a=PORT2/256;
b=PORT2%256;
printf("Entering into passvie mode n");
sprintf(write_buffer,"227 Entering Passive Mode (192,168,5,37,%d,%d) rn",a,b);
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break; 
// check =1;
//exit(0);             
}
if (strstr(read_buffer,"LIST")||strstr(read_buffer,"MLSD"))
{
sprintf(write_buffer,"150 Transfering... rn");
//printf("%sn",write_buffer);
bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
if (bytes < 0) break;

memset(write_buffer,0,sizeof(write_buffer));
//strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out rn");
// sprintf(write_buffer,"type=file;modify=20200902093315;size=302; a.cfg rn");
// sprintf(write_buffer,"a.out rn");
// sprintf(write_buffer,"%s",pwd);
// write(connfd, write_buffer, sizeof(write_buffer)); 
call_second();
memset(write_buffer,0,sizeof(write_buffer));
sprintf(write_buffer,"226 File transfer completed... rn");
//printf("%sn",write_buffer);
write(connfd, write_buffer, sizeof(write_buffer)); 
printf("wrote==%dn",n);
memset(write_buffer,0,sizeof(write_buffer));

check =1;
}
// // print buffer which contains the client contents 

}

n = 0; 


}
return NULL; 
} 
void *second_thread(void *vargp) 
{ 
while(1)
{
//printf("dfjhdkfhdfn");
// if(check==1)
// call_second();
}
}
void call_second(void)
{
int sockfd_c, connfd_c, len_c; 
struct sockaddr_in servaddr_c, cli_c; 
// socket create and verification 
sockfd_c = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd_c == -1) { 
printf("socket creation failed...2n"); 
exit(0); 
} 
else
printf("Socket successfully created..2n"); 
bzero(&servaddr_c, sizeof(servaddr_c)); 
// assign IP, PORT 
servaddr_c.sin_family = AF_INET; 
servaddr_c.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr_c.sin_port = htons(PORT2); 
// if (connect(sockfd_c, (SA*)&servaddr_c, sizeof(servaddr_c)) != 0) { 
//  printf("connection with the server failed...n"); 
//  exit(0); 
// } 
// else
//  printf("connected to the server..n"); 
// Binding newly created socket to given IP and verification 
if ((bind(sockfd_c, (SA*)&servaddr_c, sizeof(servaddr_c))) != 0) { 
printf("socket bind failed...2n"); 
exit(0); 
} 
else
printf("Socket successfully binded..2n"); 
// Now server is ready to listen and verification 
if ((listen(sockfd_c, 5)) != 0) { 
printf("Listen failed...2n"); 
exit(0); 
} 
else
printf("Server listening..2n"); 
len_c = sizeof(cli_c); 
// Accept the data packet from client and verification 
connfd_c = accept(sockfd_c, (SA*)&cli_c, &len_c); 
if (connfd_c < 0) { 
printf("server acccept failed...2n"); 
exit(0); 
} 
else
printf("server acccept the client...2n"); 

char buff[MAX]; 
int n; 
// infinite loop for chat 
//while(1)
{
if(check==1)
{


check =1;
FILE *fpipe;
int k=0;
char pwd[1500];int i=0;
char *command = "ls -l";
char c = 0;
memset(pwd,0,sizeof(pwd));


if (0 == (fpipe = (FILE*)popen(command, "r")))
{
perror("popen() failed.");
exit(EXIT_FAILURE);
}

while (fread(&c, sizeof c, 1, fpipe))
{
//printf("%c", c);
k++;
if(k>9)
pwd[i++]=c;
}
// printf("pwd==%sn",pwd);
k=0;

memset(write_buffer,0,sizeof(write_buffer));
// strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out1 rn");
// strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:14 a.out2 rn");
// strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:15 a.out3 rn");
sprintf(write_buffer,"%s",pwd);
write(connfd_c, write_buffer, sizeof(write_buffer)); 

sleep(3);

check=0; 

}
}
// After chatting close the socket 
close(sockfd_c);
printf("closed second connection...n"); 
}


int main() 
{ 
pthread_t thread_id1,thread_id2; 
printf("Before Threadn"); 
pthread_create(&thread_id1, NULL, first_thread, (void *)&thread_id1); 
//pthread_join(thread_id1, NULL); 
pthread_create(&thread_id2, NULL, second_thread, (void *)&thread_id2); 
//pthread_join(thread_id2, NULL);
printf("After Threadn"); 
pthread_exit(NULL); 
//exit(0); 
}
. 2020-09-17 16:03:04.142 Connecting to 192.168.5.37:6000 ...
. 2020-09-17 16:03:19.757 Timeout detected. (data connection)

客户端无法建立与服务器的数据连接。考虑到错误是超时而不是连接被拒绝,我怀疑客户端和服务器(或服务器上(之间存在防火墙,该防火墙正在阻止访问(丢弃流量(。但是,由于您的问题中没有可重复的内容(如代码和服务器设置(,这只是一个有根据的猜测。

大多数FTP服务器都有一个名为IP伪装的设置,如果FTP服务器位于NAT后面,则必须将其配置为公共IP地址。

该响应";227进入被动模式(192168,5,37,23112(";应该发送公共IP地址,并且服务器端的端口转发必须配置为建立连接

最新更新