2016-05-13 37 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; 
} 

服务器的源代码

#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'告诉你的字符多一个字符,你忘记了*终止符*。 –

+0

我已经在尝试调试。但是,我不知道为什么阅读功能读取比我发送的更多... –

回答

1

我试着调试你的代码。 我发现你忘记在服务器代码中为var“file_name”分配内存大小。

尝试为它分配代码中的下一行。

file_name = (char *)malloc(LEN_FILE_NAME);

的问题是可以解决的。