ข้อผิดพลาดการแบ่งส่วนในซ็อกเก็ต

ฉันมีปัญหาที่แปลกประหลาดมาก รหัสของฉันทำงานอย่างถูกต้องครั้งหนึ่ง จากนั้นฉันก็ปิดเทอร์มินัลใน linux และเปิดใหม่อีกครั้งเพื่อเรียกใช้โค้ด แต่ตอนนี้ฉันได้รับข้อผิดพลาดในการแบ่งส่วน ไม่สามารถถอดรหัสสิ่งที่เกิดขึ้นได้แน่ชัด...ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม

รหัสของฉัน:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "unistd.h"
#include <syslog.h>
#include <math.h>
#define MAXPROFILES  2

float Pearson(int mySum, int recSum, int multSum);

int main(int argc, char *argv[])
{      
   int sockfd, newsockfd, portno, clilen;
   struct sockaddr_in serv_addr, cli_addr;
   unsigned char buf[1024];

   /*int my_data2[10] = {1,3,9,10};

   int my_data[10] = {0};    //  = {1,2,3,4,5};
   int myDataBinary[500] = {0};
   int myDataBinary2[500] = {0};
   int recData[500] = {0};*/

   int index1=0;
// char* pointer = buf;

   struct profile_t
   {
      unsigned char length;
      unsigned char type;
      unsigned char *data;
   };

   typedef struct profile_datagram_t
   {
      unsigned char *src;
      unsigned char *dst;
      unsigned char ver;
      unsigned char n;
      struct profile_t profiles[MAXPROFILES];
   } header;


  header outObj;

  int j =0;
  int i =0;


  if (argc < 2) {
       fprintf(stderr,"usage: %s port_number1",argv[0]);
       exit(1);
  }

  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  if (sockfd < 0)
    error("ERROR DETECTED !!! Problem in opening socket");

  bzero((char *) &serv_addr, sizeof(serv_addr));
  portno = atoi(argv[1]);

  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(portno);

  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
          error("ERROR DETECTED !!! There was a problem in binding");

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



  printf("Server listening on port number %d...\n", serv_addr.sin_port);

  while(1){
       newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

       if (newsockfd < 0)
         error("ERROR DETECTED !!! the connection request was not accepted");

       int rc = read(newsockfd,buf,100);
       if(rc < 0){
              printf("error");
       }
       else {
            printf("success %d",rc);
       }


     outObj.src = malloc(4);// ***Editor's comment: try gdb/valgrind next time + examine your memory allocating arguments***
     outObj.dst = malloc(4);
    // printf(pointer);
     memcpy(outObj.src,buf+0,4);
     memcpy(outObj.dst,buf+4,4);
     memcpy(&outObj.ver,buf+8,1);
     memcpy(&outObj.n,buf+9,1);

      printf("\nSource IP = ");
      for(int i=0;i<4;i++){
         printf("%d ",outObj.src[i]);
      }

      printf("\nDestination IP = ");
      for(int i=0;i<4;i++){
         printf("%d ",outObj.dst[i]);
      }

      printf("\nVersion = %d",outObj.ver);
      printf("\nNumber of messages = %d",outObj.n);

      int k = 10;

      for(i=0;i<outObj.n;i++){
         memcpy(&outObj.profiles[i].length,buf+k,1);
         memcpy(&outObj.profiles[i].type,buf+k+1,1);
         outObj.profiles[i].data = malloc(outObj.profiles[i].length);
         memcpy(outObj.profiles[i].data,buf+k+2,5);
         k +=7;
      }

      for(int i=0;i<outObj.n;i++){
          printf("\n------- Message %d --------",i+1);
          printf("\nLength : %d",outObj.profiles[i].length);
          printf("\nType : %d\n",outObj.profiles[i].type);
          for(int j=0;j<5;j++){
              printf(" Data[%d] : %d",j,outObj.profiles[i].data[j]);
          }
      }

     /*
     for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
     {
         if(my_data[i] > 0){
            index1 = my_data[i];
            myDataBinary[index1] = 1;
            printf("my data %d = %d\n",index1,myDataBinary[index1]);
            }
     }

     for(int i=0; i<sizeof(my_data2)/sizeof(int);i++){
         if(my_data2[i] > 0){
            index1 = my_data2[i];
            myDataBinary2[index1] = 1;
            printf("my data %d = %d\n",index1,myDataBinary2[index1]);
          }
      }*/


     float rho;

     for(int i=0;i<outObj.n;i++){
         printf("\n\n---------- Values for Data Profile %d ------------",i+1);
         index1=0;
         int sumRecievedData = 0;
         int sumMyData = 0;
         int sumMultpliedData = 0;
         int my_data[10] = {0};//  = {1,2,3,4,5};
         int myDataBinary[500] = {0};
         int recData[500] = {0};

         if(i==0){
            my_data[0] = 1;
            my_data[1] = 3;
            my_data[2] = 9;
            my_data[3] = 10;
         } 
         else if(i==1){
            my_data[0] = 1;
            my_data[1] = 2;
            my_data[2] = 3;
            my_data[3] = 4;
            my_data[4] = 5;
         }

         for(int i=0; i<sizeof(my_data)/sizeof(int);i++){
             if(my_data[i] > 0){
                index1 = my_data[i];
                myDataBinary[index1] = 1;
                //printf("my data %d = %d\n",index1,myDataBinary[index1]);
             }
         }

         for (int j=0; j<outObj.profiles[i].length;j++) {
              if(outObj.profiles[i].data[j] > 0){
                 index1 = outObj.profiles[i].data[j];
                 recData[index1] = 1;
              }
         }

         for(int i=0;i<500;i++){
             sumRecievedData += recData[i];
             sumMyData += myDataBinary[i];
             sumMultpliedData += recData[i] * myDataBinary[i];
         }

         printf("\nrecSum = %d, \nmySum = %d, \nmultSum = %d\n",sumRecievedData,sumMyData,sumMultpliedData);

         rho = Pearson(sumMyData,sumRecievedData,sumMultpliedData);
         printf("\nPearson Coefficient for Data Profile %d= %f\n",i+1,rho);
   }









    }
    return 0;
   }


  float Pearson(int mySum, int recSum, int multSum){
     float Cov =0;
     float sdMyData = 0;
     float sdRecievedData =0;
     float rho;
     int n = 500;

     Cov = (1.0/(n-1))*(multSum - (1.0/n)*mySum*recSum);
     sdMyData = sqrt((1.0/(n-1))*(mySum - (1.0/n)*mySum*mySum));
     sdRecievedData = sqrt((1.0/(n-1))*(recSum - (1.0/n)*recSum*recSum));
     printf("\nCovariance = %f, \nVarianceMyData = %f, \nVarianceRecData = %f",Cov,sdMyData,sdRecievedData);
     if (sdMyData == 0.0 || sdRecievedData == 0.0){
         rho = 0.0;
     }
     else{
          rho = Cov/(sdMyData*sdRecievedData);
     }

     return(rho);
   }

person user537670    schedule 14.08.2011    source แหล่งที่มา
comment
โปรดรันโปรแกรมของคุณในดีบักเกอร์และแจ้งให้เราทราบว่าโปรแกรมขัดข้องตรงไหน โพสต์การติดตามสแต็กด้วย   -  person Codo    schedule 15.08.2011
comment
ประเด็นคือฉันกำลังใช้งานมันบนเครื่อง linux ระยะไกล รหัสเดียวกันนี้ทำงานได้อย่างสมบูรณ์ครั้งหนึ่ง และฉันปิดเทอร์มินัลแล้ว และตอนนี้ฉันกำลังพยายามเรียกใช้ มันแจ้งว่าการแบ่งส่วนผิดพลาด   -  person user537670    schedule 15.08.2011
comment
@ user537670: สิ่งสำคัญคือคุณแก้ไขข้อผิดพลาดในการแบ่งเซ็กเมนต์ด้วยดีบักเกอร์ เช่น GDB ซึ่งสามารถเรียกใช้จากระยะไกลได้ ดูว่ามันล่มตรงไหน และใช้ backtrace เพื่อดูว่ามันไปถึงจุดนั้นได้อย่างไร   -  person Yann Ramin    schedule 15.08.2011
comment
คุณแน่ใจเกี่ยวกับเรื่องนี้เหรอ? outObj.src = malloc(4); outObj.dst = malloc(4);   -  person jasonkim    schedule 24.02.2012
comment
ยิ่งไปกว่านั้น ตามที่ @YannRamin แนะนำ ลอง gdb แล้วคุณจะขุดมันด้วยตัวเอง   -  person jasonkim    schedule 24.02.2012


คำตอบ (1)


ฉันไม่รู้สึกอยากโพสต์คำตอบ แต่มีบางอย่างที่ฉันอยากจะตะโกนออกไปมาก

ก่อนอื่น โปรดเรียนรู้การใช้ gdb ซึ่งเป็นวิธีที่สะดวกมากในการดูว่ามีอะไรอยู่เบื้องหลัง เพิ่มตัวเลือก -g เมื่อคุณคอมไพล์ gcc -o ex ex.c -g เรียกใช้ gdb ./ex หากการคอมไพล์สำเร็จ จากนั้นในอินเทอร์เฟซคำสั่ง gdb คุณพิมพ์ run [-all sorts of arguments and options you have initially set up in your program] และ gdb จะเปิดเผยกระบวนการ/การเรียกเธรดและทุกสิ่งที่คุณต้องการ สดชื่นสบายๆ

ประการที่สอง ในโค้ดของคุณ เห็นได้ชัดว่าคุณจัดสรรหน่วยความจำในรูปแบบที่ไม่ถูกต้อง นั่นคือสิ่งที่เรามีใน man page:

 #include <stdlib.h>

 void *malloc(size_t size);
 void free(void *ptr);
 void *realloc(void *ptr, size_t size);
 void *calloc(size_t nmemb, size_t size);

ในกรณีของคุณ คุณต้องทำแบบ header_imgonnause = (header*)malloc(sizeof(header)*memoryiwannahave)

ประการที่สาม อาจเป็นอันสุดท้ายในแง่ของความผิดพลาดในการแบ่งเซ็กเมนต์ในโค้ดนี้ คุณได้ตรวจสอบ accept() read() และ write() ของคุณแล้วหรือยัง หากมีไปป์ที่เสียหายในการเชื่อมต่อ bash จะแจ้งให้คุณทราบ seg error หากใช้ gdb คุณจะรู้ ถ้าเป็นเช่นนั้น

สรุป ใช้ gdb/valgrind

person jasonkim    schedule 06.03.2012