как я могу исправить ошибку различия двоичных файлов a и b в этой программе?

#c #linux #sockets #diff #binaryfiles

#c #linux #сокеты #разница #двоичные файлы

Вопрос:

это программа для сервера и клиента передачи файлов

Как серверный, так и клиентский код я запускал нормально. Однако, когда я использовал команду diff для сравнения исходного файла и переданного файла, только двоичные файлы слов test.txt и receivefile.txt отличия» были выведены. Я знаю, что вы можете сравнивать двоичные файлы с помощью cmp, но я должен использовать diff . Как мне изменить код, чтобы я мог сравнить их с помощью команды diff?

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

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

#define BUFFSIZE 4096
#define SERVERPORT 7799

int main(void){
    int s_sock, c_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t c_addr_size;
    char buf[BUFFSIZE] = {0};
    char filename[BUFFSIZE] = {0};

    int read_len;
    int newfile;
    int writefile;
    int fileread_len;



    s_sock = socket(AF_INET, SOCK_STREAM, 0);

    bzero(amp;server_addr, sizeof(server_addr));

    int option = 1;
    setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, amp;option, sizeof(option));
    // already in use error

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVERPORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(s_sock, (struct sockaddr *) amp;server_addr, sizeof(server_addr)) == -1){
        perror("bind error");
        exit(1);
    }

    listen(s_sock,1);

    c_addr_size = sizeof(struct sockaddr);
    c_sock = accept(s_sock, (struct sockaddr *) amp;client_addr, amp;c_addr_size);
    if(c_sock == -1){
        perror("accept error");
        exit(1);
    }

   
    read_len = read(c_sock, buf, BUFFSIZE);
    if(read_len > 0){
        strcpy(filename,buf);
    }else{
        close(c_sock);
        printf("file len error");
    }

    newfile = open(filename, O_RDONLY);
    if(!newfile){
        perror("there is no file for open");
        exit(1);
    }

    while((fileread_len=read(newfile, buf, BUFFSIZE)) != 0){
        writefile = write(c_sock, buf, BUFFSIZE);
    }
    close(c_sock);
    close(newfile);
    close(s_sock);
    return 0;
}
 

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

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

#define BUFFSIZE 4096
#define SERVERPORT 7799

int main(int argc, char* argv[]){
    if(argc != 4){
        printf("<Usage : ./hw11c IP PORT FILENAME >n");
    }

    int c_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t c_addr_size;
    char buf[BUFFSIZE] = {0};
    char filename[BUFFSIZE] = {0};
    int receivefile;
    int filenamelen;
    int recv_len;

    c_sock = socket(AF_INET, SOCK_STREAM, 0);

    bzero(amp;server_addr, sizeof(server_addr));

    int option = 1;
    setsockopt(c_sock, SOL_SOCKET, SO_REUSEADDR, amp;option, sizeof(option));
    // already in use 

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi(argv[2]));
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);

    strcpy(filename,argv[3]);

    filenamelen = strlen(filename);

    if(connect(c_sock,(struct sockaddr *)amp;server_addr, sizeof(server_addr)) == -1){
        perror("connect error");
        exit(1);
    }

    send(c_sock, filename, filenamelen, 0);

    receivefile = open("receivefile.txt", O_CREAT | O_EXCL | O_WRONLY ,0700);
    // receivefile = open(filename, O_CREAT | O_EXCL | O_RDWR); 
    if(!receivefile){
        perror("there is no receive file");
        exit(1);
    }

    while((recv_len = recv(c_sock, buf, BUFFSIZE, 0)) != 0)
    {
        write(receivefile, buf, recv_len);
    }

    close(receivefile);
    close(c_sock);

    return 0;

}
 

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

1. ‘read_len = read(c_sock, buf, BUFFSIZE); if(read_len> 0){ strcpy(filename,buf); ‘ В TCP нет сообщений длиннее одного байта. Ваше предположение о том, что все имя файла, не меньше и не больше, будет загружено только одним вызовом recv(), является ложным и опасным.

2. Спасибо за совет. Но имеет ли это какое-либо отношение к этой ошибке? Я спрашиваю, потому что я действительно не знаю.

3. Кто знает? Такая же неспособность корректно и полностью обработать результаты, возвращаемые системными вызовами, применяется к send(), recv() во всем вашем коде: (

4. Как насчет этого для идеи — выполните некоторую отладку / протоколирование. Как насчет распечатки recv_len, чтобы вы могли проверить, сколько байтов было получено?

5. Подождите, что это? ‘while((fileread_len=read(newfile, buf, BUFFSIZE))!= 0){ writefile = write(c_sock, buf, BUFFSIZE);’ ??? Вы читаете ‘fileread_len’ в одной строке, затем записываете байты размера буфера в сокет? Зачем тебе это делать?