2016-05-13 34 views
-1

私はLinuxのコーディングに問題があります。ソケットプログラミングでセグメンテーションフォルトを解決するにはどうすればよいですか?

サーバにファイル名を送信すると、サーバにsegmentation faultが届きます。

これは読み取り時に発生する可能性があります。

しかし、私はそれを解決するための任意のアイデアを見つけることができません。

提案がありますか?


enter image description here

クライアントのソースコード

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

#define BUFMAX 256 

void error_handling(const char *msg) 
{ 
     fputs(msg, stderr); 
     fputc('\n', stderr); 
     exit(0); 
} 

int main(int argc, char *argv[]) 
{ 
     int sockfd, h_err; 
     int file_len = 0; 
     int buf_size = 0; 
     struct sockaddr_in serv_addr; 
     struct hostent *server; 
     char buffer[BUFMAX]; 
     FILE *file; 
     char *file_name; 
     char *file_cont; 

     if (argc < 2) 
       error_handling("ERROR! No simulator provided\n"); 

     sockfd = socket(AF_INET, SOCK_STREAM, 0); 
     if (sockfd < 0) 
       error_handling("ERROR opening socket\n"); 

     memset(&serv_addr, 0, sizeof(serv_addr)); 
     serv_addr.sin_family = AF_INET; 
     serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
     serv_addr.sin_port = htons(5000); 

     if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
       error_handling("ERROR connecting"); 

     // file handling 
     file_name = (char *)malloc(strlen(argv[1])); 
     file_len = strlen(argv[1]); 
     memcpy(file_name, argv[1], file_len); 
     file = fopen(file_name, "rb"); 
     if(file == NULL) 
       error_handling("File is not exis!\n"); 

     // send file name 
     h_err = write(sockfd, file_name, file_len); 
     if(h_err < 0) 
       error_handling("ERROR writing to socket!\n"); 

     // file handling 
     fseek(file, 0, 2); 
     file_len = ftell(file); 
     fseek(file, 0, 0); 

     // send file size 
     memset(buffer, 0, BUFMAX); 
     sprintf(buffer, "%d", file_len); 
     h_err = write(sockfd, buffer, strlen(buffer)); 
     if(h_err < 0) 
       error_handling("ERROR writing to socket!\n"); 

     file_cont = (char *)malloc(file_len); 
     while(!feof(file)) 
     { 
       fgets(buffer, BUFMAX, file); 
       memcpy(file_cont + buf_size, buffer, strlen(buffer)); 
       buf_size = strlen(buffer); 
     } 
     h_err = send(sockfd, file_cont, file_len, 0); 
     if(h_err < 0) 
       error_handling("ERROR sending to socket"); 

     printf("File sending....\n"); 

     fclose(file); 
     close(sockfd); 

     return 0; 
} 

Serverのソースコード

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

#define BUFMAX 8000 

void error_handling(const char *msg) 
{ 
     fputs(msg, stderr); 
     fputc('\n', stderr); 
     exit(1); 
} 

int main(int argc, char *argv[]) 
{ 
     int sockfd, newsockfd, h_err; 
     int file_len = 0; 
     char buffer[BUFMAX]; 
     struct sockaddr_in serv_addr, cli_addr; 
     FILE *file; 
     char *file_name; 
     char file_cont[BUFMAX]; 
     socklen_t clilen; 

     sockfd = socket(AF_INET, SOCK_STREAM, 0); 
     if (sockfd < 0) 
      error_handling("ERROR opening socket"); 

     memset(&serv_addr, 0, sizeof(serv_addr)); 
     serv_addr.sin_family = AF_INET; 
     serv_addr.sin_addr.s_addr = INADDR_ANY; 
     serv_addr.sin_port = htons(5000); 
     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
        error_handling("ERROR on binding"); 

     listen(sockfd, 5); 
     clilen = sizeof(cli_addr); 

     while(1) 
     { 
       newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
       if (newsockfd < 0) 
         error_handling("ERROR on accept"); 

       // receive file name 
       memset(buffer, 0x00, BUFMAX); 
       h_err = read(newsockfd, buffer, BUFMAX); 
       if (h_err < 0) 
       { 
         close(sockfd); 
         close(newsockfd); 
         error_handling("ERROR reading from socket"); 
       } 
       strcpy(file_name, buffer); 
       printf("File name = %s\n", file_name); 

       // receive file size 
       memset(buffer, 0, BUFMAX); 
       h_err = read(newsockfd, buffer, BUFMAX); 
       if (h_err < 0) 
       { 
         close(sockfd); 
         close(newsockfd); 
         error_handling("ERROR reading from socket"); 
       } 
       file_len = atoi(buffer); 

       // file handling 
       file = fopen(file_name, "wb"); 
       h_err = recv(newsockfd, file_cont, file_len, 0); 
       if(h_err < 0) 
       { 
         close(sockfd); 
         close(newsockfd); 
         error_handling("ERROR receive from socket"); 
       } 
       printf("Recived client file\n"); 
       fwrite(file_cont, 1, file_len, file); 

       close(newsockfd); 
     } 
     fclose(file); 
     close(sockfd); 

     return 0; 
} 
+4

あなたのコードのデバッグを解決することができます... – LPs

+4

C言語の文字列は実際には 'strlen'よりも文字が1つ多いことを忘れてしまいます。 –

+0

私はすでにデバッグを試みています。しかし、私はなぜ読んだ機能が私が送るより多くを読んだかわかりません... –

答えて

1

あなたのコードをデバッグしようとしました。 サーバーコードにvar "file_name"のメモリサイズを割り当てることを忘れてしまいました。

コードに次のような行を割り当てるようにしてください。

file_name = (char *)malloc(LEN_FILE_NAME);

問題を解決することができます。

関連する問題