2014-01-20 94 views
-1

該程序給出了分段錯誤。誰能解釋爲什麼?我嘗試使用gdb。它說,錯誤是在readFile()。我在做什麼錯誤的memcpy?我正在嘗試將文件以字節爲單位從客戶端傳輸到服務器。c中的分段故障套接字

Client.c

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


#define BUFFERSIZE 1000 
#define IPSIZE 20 
#define FILESIZE 100 


void readFile(char *name, int sock_fd) 
{ 
    FILE *fp = fopen(name, "rb"); 
    char *read_buffer, *buffer[BUFFERSIZE]; 
    unsigned long file_len; 
    int total_size = 0, flag, rem_size; 

    //Open file 

    if (!fp) 
    { 
     fprintf(stderr, "Unable to open fp %s", name); 
     return; 
    } 

    //Get file length 
    fseek(fp, 0, SEEK_END); 
    file_len=ftell(fp); 
    fseek(fp, 0, SEEK_SET); 

    //Allocate memory 
    read_buffer = (char *)malloc(BUFFERSIZE - 23); 
    if (!buffer) 
    { 
     fprintf(stderr, "Memory error!"); 
       fclose(fp); 
     return; 
    } 

    //Read file contents into buffer 

    total_size = sizeof(name) + file_len; 
    printf("Total Size: %d",total_size); 
    if(file_len < 976) 
    { 

     fread(read_buffer, sizeof(read_buffer), 1, fp); 
     memcpy(buffer, &total_size, sizeof(total_size)); 
     memcpy(buffer[sizeof(total_size)], &name, sizeof(name)); 
     memcpy(buffer[sizeof(total_size)+sizeof(name)], read_buffer, sizeof(read_buffer)); 
     flag = write(sock_fd, htonl(buffer), strlen(buffer)); 
     if (flag < 0) 
      error("ERROR writing to socket"); 
    } 
    else 
    { 
     while(1) 
     { 
      fread(read_buffer, sizeof(read_buffer), 1, fp); 
      memcpy(buffer, &total_size, sizeof(total_size)); 
      memcpy(buffer[sizeof(total_size)], &name, sizeof(name)); 
      memcpy(buffer[sizeof(total_size)+sizeof(name)], read_buffer, sizeof(read_buffer)); 
      flag = write(sock_fd, htonl(buffer), strlen(buffer)); 
      if (flag < 0) 
       error("ERROR writing to socket"); 
      rem_size = total_size - 1000; 
      if(rem_size<0) 
       break; 
     } 
    }   

    fclose(fp); 


} 


int main(int argc, char **argv) 
{ 
    struct sockaddr_in server_addr; 
    int sockfd, remote_port_no, n; 
    char remote_ip[IPSIZE], file_name[FILESIZE]; 

    if(argc!=4) 
    { 
     fprintf(stderr,"Usage: ftpc <remote-IP> <remote-port> <local-file-to-transfer>"); 
     exit(0); 
    } 


    memset(&(remote_ip), '\0', sizeof(remote_ip)+1); 
    memcpy(remote_ip, argv[1],sizeof(argv[1])+1); 
    remote_port_no = atoi(argv[2]); 
    memset(&(file_name), '\0', sizeof(file_name)+1); 
    memcpy(file_name, argv[3], sizeof(argv[3])+1); 

    puts(remote_ip); 
    puts(file_name); 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    printf("OK"); 
    if(sockfd<0) 
     printf("Socket creation ERROR"); 
    else 
     printf("Socket creation success"); 

    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(remote_port_no); 
    server_addr.sin_addr.s_addr = inet_addr(remote_ip); 
    memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); 

    if(connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 
     printf("Connect ERROR"); 
    else 
     printf("Connect Success"); 
    readFile(file_name, sockfd); 
    return 0; 
} 

Server.c

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 

#define BUFFERSIZE 1000 
#define IPSIZE 20 
#define FILESIZE 100 

int main(int argc, char **argv) 
{ 
int listen_fd, connect_fd, n, local_port_no, cli_len; 
char buffer[BUFFERSIZE]; 
struct sockaddr_in serv_addr, client_addr; 
FILE *fp; 

if(argc != 2) 
{ 
    fprintf(stderr,"Usage: ftps <local-port>"); 
    exit(0); 
} 

local_port_no = atoi(argv[1]); 

listen_fd = socket(AF_INET, SOCK_STREAM, 0); 

serv_addr.sin_family = AF_INET; 
serv_addr.sin_port = htons(local_port_no); 
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
bzero(&(serv_addr.sin_zero), sizeof(serv_addr.sin_zero)); 

bind(listen_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); 

listen(listen_fd, 1); 

cli_len = sizeof(client_addr); 

connect_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &cli_len); 

recv(connect_fd, buffer, sizeof(buffer), 0); 

fp = open("temp","wb"); 
printf("%d",sizeof(buffer)); 
fwrite(buffer, sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp); 
close(connect_fd); 

}

UPDATE

(GDB)列表 55的memcpy(緩衝液[的sizeof(TOTAL_SIZE) ],&名稱,sizeof(name)); (GDB)列表 50如果(file_len < 976) 51 { 53的fread(的read_buffer,的sizeof(的read_buffer),1,fp的); 54 memcpy(buffer,& total_size,sizeof(total_size)); 55 memcpy(buffer [sizeof(total_size)],& name,sizeof(name)); memcpy(buffer [sizeof(total_size)+ sizeof(name)],read_buffer,sizeof(read_buffer));標誌=寫入(sock_fd,htonl(緩衝區),strlen(緩衝區));
58 if(標誌< 0) 59錯誤(「錯誤寫入套接字」);

+0

你知道哪一行是故障的嗎?使用調試符號('gcc -g ...')構建並再次在'gdb'中運行。 – Macattack

+0

除了@Macattack所說的,你能把這個錯誤減少到最小范例嗎?除此之外,還有很多代碼需要閱讀。另外,如果可能的話,請包含GDB堆棧跟蹤。 –

+0

注意:'sizeof(name)','char * buffer [BUFFERSIZE];',可能它們與你想要的不同。 – BLUEPIXY

回答

0

buffer是一個指針數組。這是你的意圖嗎?

我猜不會

因此它會溢出

+0

由於它打算是一個字節數組,它不可能會超出。它很可能是預期的4倍(32位指針系統)或者預期的8倍(64位指針系統)。 –

0

存在一些明顯的問題:

  • 您使用sizeof(read_buffer)其中read_buffer是一個指向malloc分配的緩衝區。這會給你指針的大小,而不是緩衝區的大小。

  • 您使用strlen(buffer)當緩衝區包含一堆二進制數據,而不是NULL結尾的字符串。這不起作用。

+0

呵呵 - strlen()又:( –