繁体   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