2016-04-10 2 views
-3

Le but de ce serveur est de transférer de petits fichiers, de manière relativement simple. J'ai terminé le code et tout compile sans erreur, et quand j'essaie de l'exécuter, le côté serveur n'a pas de problèmes, mais le côté client donne une erreur dans la liaison de socket et une erreur de segmentation. Je me demandais ce que le code provoquait ces problèmes.Erreur de connexion de socket dans C

Serveur:

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <sys/fcntl.h> 
#include <string.h> 
#include <unistd.h> 
#include <crypt.h> 
#include <time.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <dirent.h> 
#include <netinet/ip.h> 
void timestamp_ss() 
{ 
    time_t current_time; 
    char* log_time; 

    log_time = ctime(&current_time); 
    log_file_ss(log_time); 
} 
send_data(int sockfd, char info_to_send) 
{ 
    char eof_buffer[4] = "\EOF"; 
    int sent_data, data_to_send; 
    data_to_send = strlen(&info_to_send); 

    while(data_to_send > 0) 
    { 
    sent_data = send(sockfd, &info_to_send, data_to_send, 0); 
    if(sent_data == -1) 
    perror("There was a problem in the sending of data!"); 
    data_to_send -= sent_data; 
    info_to_send += sent_data; 
    } 
    send(sockfd, eof_buffer, 4, 0); 
} 
int recv_data(int sockfd, char *dest_buffer) 
{ 
    #define EoF "\EOF" 
    unsigned char *buffer; 
    int eof_match = 0, eof_size = 2; 

    buffer = dest_buffer; 
    while(recv(sockfd, buffer, 1, 0) == 1) 
    { 
    if(*buffer == EoF[eof_match]) 
    { 
     eof_match++; 
     if(eof_match = eof_size) 
     { 
      *(buffer+1-eof_size) = '\0'; 
      return strlen(dest_buffer); 
     } 
     else 
     { 
      eof_match = 0; 
     } 
    } 
    buffer++; 
    } 
    return 0; 
} 
int password_ss(char *password_attempt, char *password_actual) 
{ 
    char key[] = { "ZjQXStSi" }; 
    char ivec[] = {"7eNP3U1b" }; 
    char des_dec[] = { "DES_DECRYPT" }; 
    char des_hw[] = { "DES_HW" }; 
    int l, i; 

    l = strlen(password_attempt); 
    i = cbc_crypt(key, password_attempt, l, *des_dec | *des_hw, ivec); 
    if(i < 0) 
    error_escape("In decryption"); 

    if(password_attempt == password_actual) 
    return 1; 
    else 
    return 0; 
} 
int log_file_ss(char *log_message) 
{ 
    char logfile[]= "/Server/log/C-File-Transfer-Server-Log"; 
    int log_fd, len; 

    log_fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT); 
    len = strlen(log_message); 
    write(log_fd, log_message, len); 
} 
void file_to_client_ss(int sockfd, struct sockaddr_in *client_addr_ptr) 
{ 
    char file_req_c[128]; 
    char buffer[10000]; 
    char files[256]; 
    char pass_attempt[128]; 
    char *error_403[20] = { "Error 403: Forbidden" }; 
    char *error_404[25] = { "Error 404: File Not Found" }; 
    char *pass_path[20] = { "/server/log/PASSWORD" }; 
    char *pass_req[50] = { "This File Requires A Password, Please Enter It Now" }; 
    char *no_pass[37] = { "This File Does Not Require A Password" }; 
    char *username; 
    char *file_s; 
    char *string; 
    char *file1_path[26] = { "/server/received_files/r_w" }; 
    char *file2_path[24] = { "/server/received_files/r" }; 
    char *file3_path[24] = { "/server/received_files/n" }; 
    char file_data; 
    FILE *cs, *ps; 
    int file1, file2, file3, file_test, pass; 

    cs = fopen(file_req_c, "r"); 
    recv_data(sockfd, username); 
    chdir("/server/log/PASSWORD"); 
    ps = fopen(username, "r"); 
    fread(files, 1, file_size(ps), ps); 
    chdir("/server"); 
    recv_data(sockfd, file_req_c); 
    file_test = file_exist(file1_path, file_req_c); 
    if(file_test = -1) 
    { 
    file_test = file_exist(file2_path, file_req_c); 
    if(file_test = -1) 
    { 
     file_test = file_exist(file3_path, file_req_c); 
      if(file_test = -1) 
      { 
       error_escape("Opening file request from client"); 
      } 
      else 
      { 
        send_data(sockfd, **pass_req); 
        recv_data(sockfd, pass_attempt); 
        pass = password_ss(pass_attempt, files); 
         if(pass == 0) 
       { 
          send_data(sockfd, **error_403); 
          error_escape("Wrong Password"); 
       } 
        else 
        { 
          if(file_exist(pass_path, username) == 0) 
           send_data(sockfd, *file_req_c); 
        else 
         errror_escape("Error in sending file"); 
         } 
      } 
     } 
     else 
     { 
     chdir(*file2_path); 
     file_data = fread(buffer, 1, file_size(cs), cs); 
     send_data(sockfd, **no_pass); 
     send_data(sockfd, file_data); 
     }  
    } 
    else 
    { 
    chdir(*file1_path); 
    file_data = fread(buffer, 1, file_size(cs), cs); 
    send_data(sockfd, **no_pass); 
    send_data(sockfd, file_data); 
    } 
} 
int file_size(FILE *stream) 
{ 
    off_t file_len; 

    fseek(stream, 0, SEEK_END); 
    file_len = ftell(stream); 
    fclose(stream); 
    return file_len; 
} 
int file_exist(char *file_path, char *file_name) 
{ 
    DIR *dp; 
    FILE *fc; 
    struct dirent *ep; 

dp = opendir(file_path); 

    if(dp == NULL) 
    perror("Opening path"); 
    else 
    chdir(file_path); 
closedir(dp); 

fc = fopen(file_name, "r"); 
    if(fc == NULL) 
    { 
    perror("Opening file"); 
    return(-1); 
    } 
    else { 
    return(0); 
} 
} 
error_escape(char *problem) 
{ 
    char error_message[256]; 

    strcpy(error_message, "! There Has Been An Error !"); 
    strncat(error_message, problem, 173); 
    perror("Error: "); 
    log_file_ss(error_message); 
    timestamp_ss(); 
    exit(-1); 
} 
void file_accept_ss(int sockfd, struct sockaddr_in *client_addr_ptr) 
{ 
    char client_request[512], username[256], file_content[8192], buf[8192]; 
    char *client_r_w[26] = { "/server/received_files/r_w" }; 
    char *client_r[24] = { "/server/received_files/r" }; 
    char *client_n[24] = { "/server/received_files/n" }; 
    char *search_string_read[6] = { "O_READ" }; 
    char *search_string_w[14] = { "O_READANDWRITE" }; 
    char *password_path[20] = { "/server/log/PASSWORD" }; 
    char *mkdir[37] = { "/server/log/PASSWORD" }; 
    char *ret; 
    char file_data, recv_i; 
    char password[256]; 
    int change_dir_test, recv_check; 
    FILE *fn, *Ps; 

    recv_data(sockfd, username); 
    recv_data(sockfd, password); 
    strcat(*mkdir, username); 
    strcat(*mkdir, password); 
    fn = fopen(*mkdir, "a"); 
    chdir(*password_path); 
    Ps = fopen(*mkdir, "a"); 
    chdir("/server"); 
    recv_i = fread(buf, 1, file_size(fn), fn); 
    recv_check = recv_data(sockfd, &recv_i); 
    if(recv_check = -1) 
    error_escape("! There Was An Error In The Receiving Of The File From The Client !"); 
    fread(file_content, 8, file_size(fn), fn); 
    ret = strstr(file_content, *search_string_read); 
    if(ret = NULL) 
    { 
    change_dir_test = chdir(*client_n); 
     if(change_dir_test = -1) 
     error_escape("! There Was An Error In The Changing Of Directories !"); 
     else 
     { 
    file_data = fread(buf, 1, file_size(Ps), Ps); 
     recv_data(sockfd, &file_data); 
     chdir(*client_n); 
    strcat(*client_n, username); 
     rename(username, *client_n); 
     } 
    } 
    if(ret = *search_string_read) 
    { 
    change_dir_test = chdir(*client_r); 
     if(change_dir_test = -1) 
     error_escape("! There Was An Error In The Changing Of Directories !"); 
     else 
     { 
     chdir(*client_r); 
     rename(username, *client_r); 
     } 
    } 
    if(ret = *search_string_w) 
    { 
    change_dir_test = chdir(*client_r_w); 
     if(change_dir_test = -1) 
     error_escape("! There Was An Error In The Changing Of Directories !"); 
     else 
     { 
     chdir(*client_r_w); 
     rename(username, *client_r_w); 
    } 
    } 
    log_file_ss("Client:"); 
    log_file_ss(username); 
    timestamp_ss(); 
} 
int main(void) 
{ 
    struct sockaddr_in server, client; 
    int sockfd, bind_test, listen_test, client_sockfd, sin_size; 

    sockfd = socket(PF_INET, SOCK_STREAM, 0); 
    if(sockfd == -1) 
    error_escape("Making Socket"); 

    server.sin_family = AF_INET; 
    server.sin_port = htons(80); 
    server.sin_addr.s_addr = INADDR_ANY; 

    bind_test = bind(sockfd, (struct sockaddr *)&server, sizeof(server)); 
    if(bind_test < 0) 
    error_escape("Binding Socket"); 
    listen_test = listen(sockfd, 20); 
    if(listen_test < 0) 
    error_escape("Listening"); 
    while(1) 
    { 
    sin_size = sizeof(struct sockaddr_in); 
    client_sockfd = accept(sockfd, (struct sockaddr *)&client, &sin_size); 
    file_accept_ss(client_sockfd, &client); 
    file_to_client_ss(client_sockfd, &client); 
    } 
shutdown(client_sockfd, SHUT_RDWR); 
return 0; 
} 

Client:

#include <stdio.h> 
#include <string.h> 
#include <dirent.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <crypt.h> 
#include <sys/socket.h> 
#include <netinet/ip.h> 



send_data(int sockfd, char info_to_send) 
{ 
    char eof_buffer[4] = "\EOF"; 
    int sent_data, data_to_send; 
    data_to_send = strlen(&info_to_send); 

    while(data_to_send > 0) 
    { 
    sent_data = send(sockfd, &info_to_send, data_to_send, 0); 
    if(sent_data == -1) 
    perror("There was a problem in the sending of data!"); 
    data_to_send -= sent_data; 
    info_to_send += sent_data; 
    } 
    send(sockfd, eof_buffer, 4, 0); 
} 
send_file_cs(int sockfd) 
{ 
    char file_buffer[4096], file_name[256]; 
    char name, username, password; 
    char *search_st, file_data, *file_location; 
    int perm_choice, password_max = 20, ch; 
    off_t size_of_file; 
    FILE *fp; 

    printf("%s\n", "Please enter the path to file you would like to move to server:"); 
    scanf("%s", &file_location); 
    ch = chdir(file_location); 
    if(ch == -1) 
    perror("! There Has Been An Error In The Directory Path !"); 
    else 
    chdir(file_location); 
    printf("%s\n", "Now Enter The Name Of The File You Would Like To Transfer:"); 
    printf("%s\n", "! Warning, The File May Not Exceed 4 kilobytes !"); 
    scanf("%s", &name); 
    printf("%s", "What would you like the username for this file to be?"); 
    name = *file_name; 
    size_of_file = file_size(fp); 
    if(size_of_file > 4096) 
    printf("! The File Is Greater Than 4 Kilobytes !"); 
    fp = fopen(file_name, "r+"); 
    printf("%s\n", "What Permissions Would You Like The File To Have?\n (1) For Other Clients To See The File\n (2) For Other CLients To See But Not Be Able To Access\n (3) Other Clients Cannot See Or Access The File"); 
    scanf("%d", &perm_choice); 
    if(perm_choice > 3 || perm_choice < 1) 
    perror("! Incorrect Permissions !"); 
    if(perm_choice = 1) 
    { 
    search_st = "O_READ"; 
    fopen(file_name, "a"); 
    fwrite(search_st, 1, strlen(search_st), fp); 
    } 
    if(perm_choice = 2) 
    { 
    search_st = "O_READANDWRITE"; 
    fopen(file_name, "a"); 
    fwrite(search_st, 1, strlen(search_st), fp); 
    } 
    if(perm_choice = 3) 
    { 
    search_st = "O_NOACCESS"; 
    fopen(file_name, "a"); 
    fwrite(search_st, 1, strlen(search_st), fp); 
    printf("%s", "Please enter a password"); 
    scanf("%s", &password); 
    send_data(sockfd, password); 
    } 
    file_data = fread(file_buffer, 1, 4096, fp); 
    send_data(sockfd, file_data); 
}  
int recv_data(int sockfd, char *dest_buffer) 
{ 
    #define EoF "\EOF" 
    unsigned char *buffer; 
    int eof_match = 0, eof_size = 2; 

    buffer = dest_buffer; 
    while(recv(sockfd, buffer, 1, 0) == 1) 
    { 
    if(*buffer == EoF[eof_match]) 
    { 
     eof_match++; 
     if(eof_match = eof_size) 
     { 
      *(buffer+1-eof_size) = '\0'; 
      return strlen(dest_buffer); 
     } 
     else 
     { 
      eof_match = 0; 
     } 
    } 
    buffer++; 
    } 
    return 0; 
} 
int password_cs(int max_length, int sockfd) 
{ 
    char salt[] = { "ZjQXStSi" }; 
    char ivec[] = { "7eNP3U1b" }; 
    char des_enc[] = { "DES_ENCRYPT" }; 
    char des_hw[] = { "DES_HW" }; 
    char password; 
    char *ret, *ret2; 
    int l, i; 

    printf("%s", "Please set your password:"); 
    scanf("%s", &password); 
    l = strlen(&password); 
    if(l > max_length) 
    printf("%s : %d", "Password must be less than", max_length); 

    i = cbc_crypt(salt, password, l, *des_enc | *des_hw, ivec); 
    if(i < 0) 
    perror("In erncryption"); 

    send_data(sockfd, password); 
    return 0; 
} 
int file_size(FILE *stream) 
{ 
    off_t file_len; 

    fseek(stream, 0, SEEK_END); 
    file_len = ftell(stream); 
    fclose(stream); 
    return file_len; 
} 
int file_exist(char *file_path, char *file_name) 
{ 
    DIR *dp; 
    FILE *fc; 
    struct dirent *ep; 

dp = opendir(file_path); 

    if(dp == NULL) 
    perror("Opening path"); 
    else 
    chdir(file_path); 
closedir(dp); 

fc = fopen(file_name, "r"); 
    if(fc == NULL) 
    { 
    perror("Opening file"); 
    return(-1); 
    } 
    else { 
    return(0); 
} 
} 
void client_request_file_cs(int sockfd) 
{ 
    char password_buf[128], file[4096], recv_file[256]; 
    char *requires[16] = { "Requires" }; 
    char *str, *restr, *file_contents, *name2, *path, *rebuf; 
    char file_req, password, name, username; 
    int test; 
    FILE *re; 

    printf("%s\n", "What file would you like from the server?"); 
    scanf("%s", &file_req); 
    printf("%s", "What is the user name associated with the file?"); 
    scanf("%s", &username); 
    send_data(sockfd, username); 
    printf("%s\n", "Where Would You Like The File To Be Put, Please Enter The Path:"); 
    scanf("%s", &path); 
    test = chdir(path); 
    if(test == -1) 
    printf("%s\n", "Invalid Path"); 
    printf("%s\n", "What Would You Like To Call The File?"); 
    scanf("%s", &name); 
    name2 = &name; 
    re = fopen(name2, "w"); 
    fread(file_contents, 1, file_size(re), re); 
    send_data(sockfd, file_req); 
    recv_data(sockfd, password_buf); 
    printf("%s\n", password_buf); 
    str = strstr(password_buf, *requires); 
    if(str == NULL) 
    recv_data(sockfd, file); 
    else 
    { 
    scanf("%s", &password); 
    send_data(sockfd, password); 
    } 
    recv_data(sockfd, rebuf); 
    fwrite(rebuf, 1, sizeof(rebuf), re); 
    fclose(re); 
    restr = strstr(file_contents, "error_"); 
    if(restr != NULL) 
    printf("%s\n", re); 
} 
int main(void) 
{ 
struct sockaddr_in client, server_addr; 
int sockfd, connected; 

server_addr.sin_family = AF_INET; 
server_addr.sin_port = htons(80); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if(sockfd == -1) 
    printf("%s", "Error opening socket"); 

connected = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 
if(connected == -1) 
    printf("%s", "Error binding socket"); 

send_file_cs(sockfd); 
client_request_file_cs(sockfd); 
shutdown(sockfd, SHUT_RDWR); 
return 0; 
} 

Nous vous remercions d'avance pour toute aide.

+2

Avez-vous traversé ce code avec un débogueur? – abelenky

+1

Je ne trouve pas comment vous définissez 'server_addr.sin_addr.s_addr' dans votre code client. Il semble que vous appelez 'connect' avec l'adresse non initialisée, ce qui est mauvais, mais peut-être pas le seul problème. –

+0

Il semble que le problème de connexion donne l'erreur "Connection Refused" –

Répondre

0

Entre autres questions/points valides dans les commentaires, l'allocation de mémoire dans votre code peut contribuer à votre segmentation fault ...

char *file_location (et d'autres) sont utilisés comme si la mémoire a été alloué.

L'utilisation de la variable dans scanf("%s", &file_location); avant d'allouer de la mémoire appelle un comportement indéfini et sera probablement (au moins partiellement) responsable de vos erreurs d'exécution.

ajouter la mémoire avant l'instruction scanf. Voici deux exemples de la façon de le faire:

1) Créer la mémoire de tas (en utilisant [m] [c] alloc):

char *file_location;  

file_location = malloc(MAX_FILENAME_LEN);//or your systems value for max directory length 
if(file_location) 
{ 
    scanf("%s", &file_location); 
    ... 

2) Utiliser la mémoire de la pile: (pointer votre pointeur vers un lieu avec mémoire)

char file_name[256]; 
char *file_location = file_name; 

file_location = file_name; 
scanf("%s", &file_location); 

Mais la façon la plus simple (s'il n'y a rien que vous contraignant d'utiliser un pointeur) serait de créer simplement la variable sur la pile et l'utiliser dans scanf(...):

char file_location[256]; 

scanf("%s", &file_location); 

Il existe d'autres variables (en plus de file_location) dans votre exemple de code qui ont besoin de mémoire avant utilisation. N'oubliez pas de libérer toute variable avec la mémoire créée on the heap lorsque vous avez terminé d'utiliser.

+0

Après avoir essayé les deux, il renvoie toujours l'erreur "Bad Address", peu importe l'adresse que j'ai mis. –

+0

@WinnerInc - J'ai offert le problème/solution de création de mémoire comme un des problèmes potentiels avec votre exemple de code qui devra être adressé avant que vous l'obteniez à courir. Avez-vous initialisé 'server_addr.sin_addr.s_addr' n'importe où? Avez-vous essayé de passer par un débogueur vous-même? (Je le ferais, sauf que je ne suis pas proche de mon compilateur pour le moment) – ryyker

0

erreur de liaison

Il n'y a pas d'erreur de se lier ici. Le client ne fait pas de liaison du tout. Il obtient une erreur connectant le socket, puis imprime de façon trompeuse «erreur de liaison». L'erreur de connexion est due au fait que vous n'initialisez pas le champ d'adresse de la cible à laquelle vous essayez de vous connecter.

NB vous n'avez pas besoin de \ EOF. recv() retournera zéro lorsque l'homologue se déconnecte, ce que vous ne vérifiez pas. Vous ne le vérifiez pas non plus pour des erreurs. C'est un code très étrange. - EJP 19 mins ago