2016-04-10 13 views
-3

このサーバーの目的は、比較的簡単な方法で小さなファイルを転送することです。私はコードを完了し、それはすべてエラーなしでコンパイルし、私はそれを実行しようとすると、サーバー側は問題はありませんが、クライアント側は、ソケットバインディングとセグメンテーションエラーでエラーを返します。コード内で何がこれらの問題を引き起こしているのだろうと思っていました。Cでのソケット接続エラー

サーバー:

#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; 
} 

クライアント:

#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; 
} 

は、任意の助けを事前にありがとうございます。メモリが割り当てられているかのようにコメント内の他の有効な質問/点のうち

+2

このコードをデバッガでステップしましたか? – abelenky

+1

クライアントコードに 'server_addr.sin_addr.s_addr'をどのように設定したのかわかりません。初期化されていないアドレスを 'connect'と呼びますが、それは悪いですが、唯一の問題ではないかもしれません。 –

+0

接続の問題が「接続が拒否されました」というエラーが表示されるように見えます –

答えて

0

、あなたのコード内のメモリ割り当ては、あなたのセグメンテーションフォールトに貢献することができる...

char *file_location(その他)が使用されています。

メモリを割り当てる前にscanf("%s", &file_location);に変数を使用すると、未定義の動作が呼び出され、実行時エラーが発生する可能性があります。

の前に、のscanfステートメントを追加します。ここではそれを行う方法の2つの例です。)

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スタックメモリを使用します:

1)[M]、[C]のalloc)を使用して、(ヒープメモリを作成します(場所にポインタを指します

char file_location[256]; 

scanf("%s", &file_location); 
:メモリ)

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

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

しかし、最も簡単な方法(あなたは、ポインタを使用することを制約するものがない場合)だけscanf(...)でそれをスタック上に変数を作成して使用することであろうと

例コードには、使用する前にメモリが必要な他の変数(file_location以外)があります。使用し終わったら、メモリを持つ任意の変数をフリーにすることを忘れないでください。on the heap

+0

これらの両方を試した後も、私が入れたアドレスに関係なくエラー "Bad Address"が返されます。 –

+0

@WinnerInc - 私は、メモリ作成の問題/解決策を、実行する前に対処する必要があります。どこでも 'server_addr.sin_addr.s_addr'を初期化しましたか?あなたは自分でデバッガでステップアップしようとしましたか? (私は、私がこの時点でコンパイラに近づいていないことを除いて) – ryyker

0

バインドエラー

は、ここには、バインドエラーはありません。クライアントはまったくバインドを行いません。エラーをソケットに接続すると、誤って「バインドエラー」が表示されます。

接続エラーは、接続しようとしているターゲットのアドレスフィールドを初期化していないためです。

NBあなたは\ EOFは必要ありません。 recv()は、ピアが切断したときにゼロを返します。これはチェックしていません。エラーがないかチェックしていません。これは非常に奇妙なコードです。 - EJP 19 minutes ago ago