简体   繁体   中英

How do i fix my pipe in linux socket program?

I included some of my code,when i run my program (server) everything works fine except for the pipe i am really not sure where to problem is, the output always prints 0 and both error messages get printed out.(dots represent chunks of code i left out) First the program makes connection with client and then the communication begins, at the end of communication pipe in child process is suppose to send variable hours to pipe in the parent process.

#define PORT 4444
#define BUF_SIZE 2000
#define CLADDR_LEN 100

void func(int subor,int rychlost,int *h,int *m,int *s){

    int hours,minutes,seconds,inputSecond;
    int remainingSeconds;
    
    int secondsInHour = 60 * 60;
    int secondsInMinute = 60;
    
    
    
    subor *= 8000;
    rychlost *= 1000;
    
    inputSecond = subor/rychlost;

    hours = (inputSecond/secondsInHour);


    remainingSeconds = inputSecond - (hours * secondsInHour);
    minutes = remainingSeconds/secondsInMinute;


    remainingSeconds = remainingSeconds - (minutes*secondsInMinute);
    seconds = remainingSeconds;
    
    *h=hours;
    *m=minutes;
    *s=seconds;

}

void main() {
 struct sockaddr_in addr, cl_addr;
 int sockfd, len, ret, newsockfd,fileSize,speed;
 char buffer[BUF_SIZE]="Type 'start' or 'exit'\n";
 pid_t childpid;
 int hours,minutes,seconds;
 int fd[2];

 
 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0) {
  printf("Error creating socket!\n");
  exit(1);
 }
 printf("Socket created...\n");
 
 memset(&addr, 0, sizeof(addr));
 addr.sin_family = AF_INET;
 addr.sin_addr.s_addr = INADDR_ANY;
 addr.sin_port = PORT;
 
 ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
 if (ret < 0) {
  printf("Error binding!\n");
  exit(1);
 }
 printf("Binding done...\n");

 printf("Waiting for a connection...\n");
 listen(sockfd, 5);

 for (;;) { 
  len = sizeof(cl_addr);
  newsockfd = accept(sockfd, (struct sockaddr *) &cl_addr, &len);
  if (newsockfd < 0) {
   printf("Error accepting connection!\n");
   exit(1);
  }
  printf("Connection accepted...\n");


  if ((childpid = fork()) == 0) { 
    close(fd[0]);
   close(sockfd); 


        ret = send(newsockfd, buffer, BUF_SIZE, 0);   
    if (ret < 0) {  
     printf("Error sending data!\n");  
     exit(1);  
    }  
    
   for (;;) {
    memset(buffer, 0, BUF_SIZE);
    

    
    ret = recv(newsockfd, buffer, BUF_SIZE, 0);
    if(ret < 0) {
     printf("Error receiving data!\n");  
     exit(1);
    }
 
     
       if (strcmp(buffer, "start\n") == 0)  {
       
        ret = send(newsockfd, "Type size of file in [Mb]\n", BUF_SIZE, 0);   
        if (ret < 0) {  
         printf("Error sending data!\n");  
         exit(1);  
        }  
        
            ret = recv(newsockfd, buffer, BUF_SIZE, 0);
            if(ret < 0) {
             printf("Error receiving data!\n");  
             exit(1);
            }
         
        fileSize = atoi(buffer);
         
         ret = send(newsockfd, "Type Speed of internet in [MB]\n", BUF_SIZE, 0);   
          if (ret < 0) {  
          printf("Error sending data!\n");  
          exit(1);  
            } 
             
          ret = recv(newsockfd, buffer, BUF_SIZE, 0);
            if(ret < 0) {
             printf("Error receiving data!\n");  
             exit(1);
            }
         
        speed = atoi(buffer);
        
        func(fileSize,speed,&hours,&minutes,&seconds);
        
        buffer[BUF_SIZE] = sprintf(buffer,"Upload bude trvat %d:%d:%d\n",hours,minutes,seconds);
        
        
        if((write(fd[1], &hours,sizeof(int))) == -1){   \\problem is here
            printf("write error\n"); 
            }
        close(fd[1]);
        
        ret = send(newsockfd, buffer, BUF_SIZE, 0);   
          if (ret < 0) {  
          printf("Error sending data!\n");  
          exit(1);  
            } 
             
        exit(0); 
            }
    
   }
  }else{
    wait();
    close(fd[1]);
    int fin;
    

    if((read(fd[0], &fin, sizeof(int))) == -1){   \\problem is here
    printf("read error\n"); 
    }
 
    
    
    printf("%d\n",fin); 
    close(fd[0]);
  }
  close(newsockfd);
 }
}

Well, after solving some of the problems in the code you sent, I think I've got your code running:

$ netstat -p -l | grep pru28763
tcp        0      0 0.0.0.0:23569           0.0.0.0:*               ESCUCHAR    46607/pru28763      
$ _

your process is actually listening, but not in port 4444 , but in port 46607 . This means you have not converted the port number into network byte order by calling htons() macro. And you need to do.

I'll send you a diff with all the corrections made to your code, to make it run, but you don't initialize the array fd[] and, as I don't know how do you want to use it (there's no call to pipe(2) in your posted code) I cannot further help you:

diff --git a/pru28763.c b/pru28763.c
index 78792e9..a6b7c7d 100644
--- a/pru28763.c
+++ b/pru28763.c
@@ -57,7 +57,7 @@ void main() {
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = PORT;
+ addr.sin_port = htons(PORT);
  
  ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
  if (ret < 0) {
@@ -84,7 +84,7 @@ void main() {
    close(sockfd); 
 
 
-        ret = send(newsockfd, buffer, BUF_SIZE, 0);   
+        ret = send(newsockfd, buffer, strlen(buffer), 0);   
     if (ret < 0) {  
      printf("Error sending data!\n");  
      exit(1);  
@@ -102,25 +102,32 @@ void main() {
     }
  
      
-       if (strcmp(buffer, "start\n") == 0)  {
+       char *startmsg = "start\n";
+       if (strncmp(buffer,  startmsg, strlen(startmsg)) == 0)  {
        
-        ret = send(newsockfd, "Type size of file in [Mb]\n", BUF_SIZE, 0);
+       char *msg = "Type size of file in [Mb]\n";
+        ret = send(newsockfd, msg, strlen(msg), 0);
  
         if (ret < 0) {  
          printf("Error sending data!\n");  
          exit(1);  
         }  
         
-            ret = recv(newsockfd, buffer, BUF_SIZE, 0);
+           /* to allow for a \0 that must be put at the end of what
+             * is received */
+            ret = recv(newsockfd, buffer, BUF_SIZE - 1, 0);
             if(ret < 0) {
              printf("Error receiving data!\n");  
              exit(1);
             }
          
+
+           buffer[ret] = '\0';
         fileSize = atoi(buffer);
          
-         ret = send(newsockfd, "Type Speed of internet in [MB]\n",
-BUF_SIZE, 0);   
+           msg = "Type Speed of internet in [MB]\n";
+   
+         ret = send(newsockfd, msg, strlen(msg), 0);
           if (ret < 0) {  
           printf("Error sending data!\n");  
           exit(1);  
@@ -131,6 +138,10 @@ BUF_SIZE, 0);
              printf("Error receiving data!\n");  
              exit(1);
             }
+
+           /* again, you must end a buffer read with a \0 if you
+             * want it to be checked with string routines */
+           buffer[ret] = '\0';
          
         speed = atoi(buffer);
         
@@ -139,6 +150,7 @@ BUF_SIZE, 0);
         buffer[BUF_SIZE] = sprintf(buffer,"Upload bude trvat %d:%d:%d\n",hours,minutes,seconds);
         
         
+       /* fd array has not been initialized, no pipe(2) call shown */
         if((write(fd[1], &hours, sizeof(int))) == -1){   /*problem is here */
             printf("write error\n"); 
             }
@@ -162,6 +174,8 @@ BUF_SIZE, 0);
     int fin;
     
 
+   /* no initialization of array fd, no pipe call shown in the snippet
+    * sent */
     if((read(fd[0], &fin, sizeof(int))) == -1){   /*problem is here */
     printf("read error\n"); 
     }

by the way, the problem is in neither one of the places your mark as candidates, but in that you insist in sending a text message by using send(2) without specifying the data length, so you send the full buffer, despite of what contents could it have. Also, you read a full buffer and then use strcmp(3) to check for a string. The client could buffer its output, and send you a full 1500 bytes block of data, starting with 'start\n' and that will result in not recognizing the starting subsequence.

I give up with your code, it required me to dedicate more than a full hour of my time and this is not what we all want. My apologies. Try to repair (and understand) all the modifications I've done to your code. Next time, at least, format it adequately to be readable at least. Indentation is fundamental to understand the program logic, and you have not dedicated enough time to make things easier to the people reading your code. Please, read How to create a Minimal, Reproducible Example to see how code must be sent to this forum.

connect() is missing after forking the child process.

You have used newsockfd to send the data from the child process. newsockfd is the return value of accept system call. This is wrong.

Read: https://www.geeksforgeeks.org/tcp-server-client-implementation-in-c/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM