2016-11-10 70 views
0

我們的任務是在一個c代碼中創建一個雙向通信模擬。這是我第一次用這樣的代碼,所以我創造了這個簡單的代碼涉足:C-用戶輸入「退出」後,使用叉的程序不會退出

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include<wait.h> 
int main(void) 
{ 
    pid_t pid; 
    char buf[1024]; 
    char cp[50]; 
    char ex[100]="exit"; 
    int readpipe[2]; 
    int writepipe[2]; 
    long int a; 
    int b; 
    a=pipe(readpipe); 
    b=pipe(writepipe); 
    int test=1; 
    int length; 

    if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); } 
    if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); } 
    fflush(stdin); 
    pid=fork(); 
    if(pid==-1) 
     { 
      printf("pid:main"); 
      exit(1); 
     } 
    while(test==1) 
     { 
      if(pid==0) 
       { 
        close(readpipe[1]); 
        close(writepipe[0]); 
        if(read(readpipe[0],buf,sizeof(buf)) < 0) 
         { 
          exit(1); 
         } 
        printf("\nSEND TO USER 1:"); 
        fflush(stdin); 
        fgets(cp, 50, stdin); 
        length = strlen(cp); 
        if(cp[length-1] == '\n') { 
         --length; 
         cp[length] = '\0'; 
        } 
        if(strcmp(cp,ex)==0) { 
         test=0; 
         break; 
        } 
        if(write(writepipe[1],cp,strlen(cp)+1) < 0) 
         { 
          exit(1); 
         } 
       } 
      else 
       { 
        close(readpipe[0]); 
        close(writepipe[1]); 
        printf("\nSEND TO USER 2:"); 
        fflush(stdin); 
        fgets(cp, 50, stdin); 
        length = strlen(cp); 
        if(cp[length-1] == '\n') { 
         --length; 
         cp[length] = '\0'; 
        } 
        if(strcmp(cp,ex)==0) { 
         test=0; 
         break; 
        } 
        if(write(readpipe[1],cp,strlen(cp)+1) < 0) 
         { 
          exit(1); 
         }   

        if(read(writepipe[0],buf,sizeof(buf)) < 0) 
         { 
          exit(1); 
         }   
       } 
     } 
    close(readpipe[1]); 
    close(writepipe[0]); 
    close(readpipe[0]); 
    close(writepipe[1]); 
    return 0; 
} 

程序終止時,用戶1或用戶2輸入退出。但是......

錯誤在於,無論何時按下退出鍵,都會首先打印「發送給用戶x」,然後繼續退出。我怎樣才能解決這個問題?任何幫助?謝謝。

+0

從管道讀取時,您從來沒有檢查EOF,你只檢查錯誤。 – Barmar

回答

0

當您在發送過程中鍵入exit時,它會跳出循環,關閉其管道末端並退出。

當另一個進程試圖從管道讀取時,它將得到一個EOF,這表示read()返回0。但是你的代碼從不檢查這個,它只在read()write()返回一個負值表示一個錯誤(EOF不是錯誤)時退出。因此它回到循環的頂部並要求輸入發送到其他進程。當它試圖寫入封閉的管道時,它將得到EPIPE錯誤或SIGPIPE信號,然後它將退出。

更改您的閱讀代碼:

int n = read(readpipe[0],buf,sizeof(buf)); 
if (n == 0) { 
    break; 
} else if (n < 1) { 
    exit(1); 
} 
+0

我是否需要將兩個閱讀代碼都更改爲兩個管道?因爲我已經嘗試過了,輸入「發送給用戶2」後,程序打印發送給用戶1,然後終止。我試着只是改變發送給用戶2的閱讀代碼,並且它的工作原理,但只有當你輸入exit才能發送給用戶2.謝謝你的幫助。 –

+0

是的,你需要改變它們,因爲你可以輸入'exit'到任一進程,然後另一個進程也應該退出。 – Barmar

+0

輸入內容後立即終止發送給用戶2.任何想法爲什麼發生這種情況? –