簡體   English   中英

如何在 linux 套接字程序中修復我的 pipe?

[英]How do i fix my pipe in linux socket program?

我包含了我的一些代碼,當我運行我的程序(服務器)時,一切正常,除了 pipe 我真的不確定問題出在哪里,output 總是打印 0 並且兩個錯誤消息都被打印出來。(點代表塊我省略了代碼)首先程序與客戶端建立連接,然后開始通信,在通信結束時子進程中的 pipe 假設將變量小時發送到父進程中的 pipe。

#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);
 }
}

好吧,在解決了您發送的代碼中的一些問題之后,我想我已經讓您的代碼運行了:

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

您的進程實際上正在偵聽,但不在端口4444中,而是在端口46607中。 這意味着您沒有通過調用htons()宏將端口號轉換為網絡字節順序。 你需要這樣做。

我將向您發送一個包含對您的代碼所做的所有更正的差異,以使其運行,但您沒有初始化數組fd[]並且,因為我不知道您想如何使用它(沒有在您發布的代碼中調用pipe(2) )我無法進一步幫助您:

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"); 
     }

順便說一句,問題不在於您標記為候選人的任何一個地方,而是因為您堅持使用send(2)發送文本消息而不指定數據長度,因此您發送完整的緩沖區,盡管內容可能有。 此外,您讀取了一個完整的緩沖區,然后使用strcmp(3)檢查字符串。 客戶端可以緩沖它的 output,並向您發送一個完整的 1500 字節數據塊,以“start\n”開頭,這將導致無法識別起始子序列。

我放棄了你的代碼,它需要我花費一個多小時的時間,這不是我們都想要的。 我很抱歉。 嘗試修復(並理解)我對您的代碼所做的所有修改。 下一次,至少,將其格式化為至少可讀。 縮進是理解程序邏輯的基礎,你沒有花足夠的時間讓閱讀你的代碼的人更容易理解。 請閱讀如何創建一個最小的、可重現的示例以了解如何將代碼發送到此論壇。

分叉子進程后,connect() 丟失。

您已使用newsockfd從子進程發送數據。 newsockfd是接受系統調用的返回值。 這是錯誤的。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM