проблема с реализацией «СПИСКА» ftp-сервера

#networking #tcp #ftp #winscp

#сеть #tcp #ftp #winscp

Вопрос:

Я внедряю FTP-сервер, здесь делаю winscp в качестве клиента.всякий раз, когда клиент отправляет команду PASV мне (серверу), я даю ответ с IP-адресом и портом клиенту, затем клиент отправляет команду СПИСКА, затем я даю ответ клиенту как

 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 всегда показывает «8failed для извлечения списков каталогов **»

но если я вижу в журналах 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)
  

Но на сервере отображается, что клиент подключен.

здесь я не могу выяснить, почему ответ для списка не отправляется

Может ли кто-нибудь мне помочь

Вот мой код

 #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(amp;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*)amp;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*)amp;cli, amp;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(amp;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%6;
                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(amp;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*)amp;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*)amp;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*)amp;cli_c, amp;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(amp;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(amp;thread_id1, NULL, first_thread, (void *)amp;thread_id1); 
    //pthread_join(thread_id1, NULL); 
    pthread_create(amp;thread_id2, NULL, second_thread, (void *)amp;thread_id2); 
    //pthread_join(thread_id2, NULL);
    printf("After Threadn"); 
    pthread_exit(NULL); 
    //exit(0); 
}
  

Комментарии:

1. мартин, я новичок в этом переполнении стека, хорошо, у вас есть какой-либо ответ на это, я был поражен здесь

2. @MartinPrikryl я отредактировал свой код, пожалуйста, проверьте

3. @martin теперь я обновил свой код, он понятен, и я открыл порт 6004

4. @martin я проверял порты 6000 и 6004 на обоих портах, оба открыты

5. @MartinPrikryl любое решение для этого

Ответ №1:

 . 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)
  

Клиенту не удается установить соединение для передачи данных с сервером. Учитывая, что ошибка — это тайм-аут, а не отказ в соединении, я подозреваю, что между клиентом и сервером (или на сервере) существует брандмауэр, который блокирует доступ (отбрасывает трафик). Но, поскольку в вашем вопросе нет ничего воспроизводимого (например, кода и настройки сервера), это всего лишь обоснованное предположение.

Комментарии:

1. Здесь все, что я реализую локально, мой сервер и клиент находятся в локальной сети. еще одна вещь — произошло запуск управляющего соединения и обмен командами.

2. @Srihari: локальная сеть не исключает брандмауэры на самой машине. И снова — без каких-либо дополнительных подробностей (код, настройка сервера) можно только догадываться, что происходит.

3. @Srihari: предполагается, что сервер не просто отправляет ответ PASV на управляющее соединение, а фактически прослушивает заданный IP-адрес и порт и ожидает подключения к клиенту (подключение для передачи данных). Меня раздражает, что вы никогда не упоминаете эту часть, поэтому, возможно, вы просто не реализуете ее. И снова — по-прежнему нет кода.

Ответ №2:

Большинство FTP-серверов имеют параметр, называемый IP masquerade, который должен быть настроен на общедоступный IP-адрес, если сервер FTP находится за NAT.

этот ответ «227 Вход в пассивный режим (192 168,5,37,23,112) » должен отправлять общедоступный IP-адрес, и для установления соединения должна быть настроена переадресация портов на стороне сервера

Комментарии:

1. Джон, я все внедряю локально