клиент сервер TCP IP программа для загрузки файла и списка файлов в каталоге на Ubuntu

#c #tcp #server #ip #tcp-ip

#c #tcp #сервер #ip #tcp-ip

Вопрос:

Я не знаю, почему он попадает в бесконечный цикл и не загружает файл, когда я пытаюсь выполнить эту командную строку:

./сервер 2000

./client получить имя файла localhost 2000 256

У меня есть два сомнения. Первый из них заключается в том, почему список файлов содержит несколько точек. Во-вторых, почему я не могу загрузить файл из каталога сервера.

клиентский код

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> 
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>


void error(const char *msg)
{
perror(msg);
exit(0);
}

int main(int argc, char *argv[])
{
int file_size;
FILE *received_file;
int remain_data = 0;
ssize_t len;

int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;

char buffer[256];
int TamBuffer;
if (argc < 3) {
   fprintf(stderr,"usage %s hostname portn", argv[0]);
   exit(0);
}

if(strcmp(argv[1],"list")==0){

TamBuffer=atoi(argv[4]);
char *comando = argv[1];
portno = atoi(argv[3]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
    error("ERROR opening socket");
server = gethostbyname(argv[2]);
if (server == NULL) {
    fprintf(stderr,"ERROR, no such hostn");
    exit(0);
}
bzero((char *) amp;serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
     (char *)amp;serv_addr.sin_addr.s_addr,
     server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) amp;serv_addr,sizeof(serv_addr)) < 0)
    error("ERROR connecting");

n=write(sockfd,comando,strlen(comando));
if (n < 0)
error("ERROR writing to socket");

bzero(buffer,TamBuffer);



bzero(buffer,TamBuffer);
n = read(sockfd,buffer,TamBuffer-1);
if (n < 0)
     error("ERROR reading from socket");
printf("%sn",buffer);

close(sockfd);
}

if (strcmp(argv[1],"get")==0){
TamBuffer=atoi(argv[5]);
char *comando = argv[1];
portno = atoi(argv[4]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
    error("ERROR opening socket");
server = gethostbyname(argv[3]);
if (server == NULL) {
    fprintf(stderr,"ERROR, no such hostn");
    exit(0);
}
bzero((char *) amp;serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
     (char *)amp;serv_addr.sin_addr.s_addr,
     server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) amp;serv_addr,sizeof(serv_addr)) < 0)
    error("ERROR connecting");
strcat(comando,argv[2]);
n=write(sockfd,comando,strlen(comando));

if (n < 0)
error("ERROR writing to socket");



 /* Receiving file size */
    recv(sockfd, buffer, TamBuffer, 0);
    file_size = atoi(buffer);
    fprintf(stdout, "nFile size : %dn", file_size);

    received_file = fopen("newfile", "w");
    if (received_file == NULL)
    {
    fprintf(stderr, "Failed to open file foo --> %sn", strerror(errno));

    exit(EXIT_FAILURE);
    }

    remain_data = file_size;

    while (((len = recv(sockfd, buffer, TamBuffer, 0)) > 0) amp;amp; (remain_data > 0))
    {
            fwrite(buffer, sizeof(char), len, received_file);
            remain_data -= len;
            int received_byte = len;
            fprintf(stdout, "Receive %d bytes and we hope :- %d bytesn", received_byte, remain_data);
    }
    fclose(received_file);



close(sockfd);



}
return 0;
}
 

серверный код

 #include <errno.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/sendfile.h>



void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{


int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
int sent_bytes = 0; // bytes de envio de arquivo
char file_size[256]; //tamanho do arquivo
struct stat file_stat;
off_t offset;
int remain_data;
ssize_t len;
int fd;

if (argc < 2) {
     fprintf(stderr,"ERROR, no port providedn");
     exit(1);
 }
 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0)
    error("ERROR opening socket");
 bzero((char *) amp;serv_addr, sizeof(serv_addr));
 portno = atoi(argv[1]);
 serv_addr.sin_family = AF_INET;
 serv_addr.sin_addr.s_addr = INADDR_ANY;
 serv_addr.sin_port = htons(portno);
 if (bind(sockfd, (struct sockaddr *) amp;serv_addr,
          sizeof(serv_addr)) < 0)
          error("ERROR on binding");
 listen(sockfd,5);
 clilen = sizeof(cli_addr);
 newsockfd = accept(sockfd,
             (struct sockaddr *) amp;cli_addr,
             amp;clilen);
 if (newsockfd < 0)
      error("ERROR on accept");
 bzero(buffer,256);
 n = read(newsockfd,buffer,255);
 if (n < 0) error("ERROR reading from socket");

if(strcmp("list",buffer)==0){

 DIR           *d;
 struct dirent *dir;
 d = opendir(".");
 if (d)
 {
     while ((dir = readdir(d)) != NULL)
    {
    n=write(newsockfd,dir->d_name,strlen(dir->d_name));
    n=write(newsockfd, "n",1);
    if (n < 0) error("ERROR writing to socketn");
   }

 closedir(d);
 }
 }
else {
    n = read(newsockfd,buffer,255);
    if (n < 0) error("ERROR reading from socket");
    int i;
    for(i=0;i<strlen(buffer);i=i 1){
        buffer[i]=buffer[3 i];
    }
    printf("%sn",buffer);

    char* FILE_TO_SEND = buffer;

    fd = open(FILE_TO_SEND, O_RDONLY);
    if (fd == -1)
    {
            fprintf(stderr, "Error opening file --> %s", strerror(errno));

            exit(EXIT_FAILURE);
    }

    /* Get file stats */
    if (fstat(fd, amp;file_stat) < 0)
    {
            fprintf(stderr, "Error fstat --> %s", strerror(errno));

            exit(EXIT_FAILURE);
    }
    int num_filesize = file_stat.st_size;
    fprintf(stdout, "File Size: n%d bytesn", num_filesize);


    /* Sending file size */
    len = send(newsockfd, file_size, sizeof(file_size), 0);
    if (len < 0)
    {
    fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));

          exit(EXIT_FAILURE);
    }

    printf("teste1/n");

    int num_bytes_sent= len;
    fprintf(stdout, "Server sent %d bytes for the sizen", num_bytes_sent);

    offset = 0;
    remain_data = file_stat.st_size;
    /* Sending file data */

    printf("teste2/n");
    while (((sent_bytes = sendfile(newsockfd, fd, amp;offset, 256)) > 0) amp;amp; (remain_data > 0))
    {
            fprintf(stdout, "1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %dn", sent_bytes, offset, remain_data);
            remain_data -= sent_bytes;
            fprintf(stdout, "2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %dn", sent_bytes, offset, remain_data);
    }



}
 close(newsockfd);
 close(sockfd);
 return 0;
}
 

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

1. Ну, одна вещь сразу ошибочна, порядок по условной оценке неверен в вашем клиентском цикле. (remain_data > 0) должно быть проверено первое условие; не последнее. Устраняет ли это вашу проблему или нет, как написано, это неправильно.

2. Предлагаю вам использовать отладчик. Это поможет вам гораздо больше в решении этой проблемы и в вашей долгосрочной карьере научиться эффективно использовать отладчик.

3. Я также не вижу, где вы на самом деле заполняете содержимое file_size перед отправкой его в 256 байт по каналу с вашего сервера, поэтому, что бы ни получал клиент, это мусор. Он ожидает, что завершенная строка цифр будет соответствовать размеру файла.