2013-03-13 57 views
0

我創建了兩個進程通信的應用程序。一切都很好 但我想,當用戶按Esc的過程中自動結束。 s * 其次它從用戶只獲得一行。在一個過程中一次 *。並且在進入第二行之前,我們還必須向另一個進程添加一行。 這裏是過程1中的代碼(我稱爲服務器)c中的基於控制檯的聊天應用程序

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/errno.h> 
extern int  errno; 
#define FIFO1 "/tmp/fifo.1" 
#define FIFO3 "/tmp/fifo.3" 
#define PERMS 0666 
#define MESSAGE1  "client Says:" 

main() 
{ 
    char buff[BUFSIZ]; 
    int readfd, writefd; 
int n, size; 
    if ((mknod (FIFO1, S_IFIFO | PERMS, 0) < 0) && (errno != EEXIST)) { 
     perror ("mknod FIFO1"); 
     exit(1); 
    } 
    if (mkfifo(FIFO3, PERMS) < 0 && (errno != EEXIST)) { 
     unlink (FIFO1); 
     perror("mknod FIFO3"); 
     exit(1); 
    } 
    if ((readfd = open(FIFO1, 0)) < 0) { 
     perror ("open FIFO1"); 
     exit(1); 
    } 
    if ((writefd = open(FIFO3, 1)) < 0) { 
     perror ("open FIFO3"); 
     exit(1); 
    } 
/////////////////////////////////////////////////////////////////////////////////////////////////////// 
loop: 
while(1) 
{ 



    if ((n = read(readfd, buff, 100)) < 0) { 
     perror ("server read"); exit (1); 
    } 

write(1,MESSAGE1,strlen(MESSAGE1)); 
if (write(1, buff, n) != n) { 
      perror ("client write2"); exit(1); 
     } 


///////////////////////////////////////////////////////////////////////////////////////////// 


while(1) 
{ 

printf("server says:"); 
//strcpy(buff,"I say:"); 
fgets(buff,100,stdin); 
n=strlen(buff) + 1; 
    if (write(writefd, buff,n) < n) { 
     perror("server write1"); exit (1); 
    } 
goto loop; 
} 

}//end of first for 
    close (readfd); close (writefd); 
} 

第二種方法(我稱爲客戶端)

#include <stdio.h> 
#include <string.h> 
#include<stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/errno.h> 
extern int  errno; 
#define FIFO1 "/tmp/fifo.1" 
#define FIFO3 "/tmp/fifo.3" 
#define PERMS 0666 
#define MESSAGE1  "server Says:" 


main() 
{ 
    char buff[BUFSIZ]; 
char buf[]="logout"; 
    int readfd, writefd, n, size; 
    if ((writefd = open(FIFO1, 1)) < 0) { 
     perror ("client open FIFO1"); exit(1); 
    } 
    if ((readfd = open(FIFO3, 0)) < 0) { 
     perror ("client open FIFO3"); exit(1); 
    } 
/////////////////////////////////////////////////////////// 
loop: 
while(1) 
{ 

printf("client says:"); 
fgets(buff,100,stdin); 
n=strlen(buff) + 1; 
    if (write(writefd, buff,n) < n) 
    { 
     perror("server write1"); exit (1); 
     } 

//////////////////////////////////////////// 
while(1) 
{ 


    if ((n = read(readfd, buff, 100)) < 0) 
    { 
     perror ("client read"); exit(1); 
     } 


    write(1,MESSAGE1,strlen(MESSAGE1)); 
     if (write(1, buff, n) != n) 
     { 
      perror ("client write2"); exit(1); 
     } 


goto loop; 
} 
}//end of first for 
    close(readfd); close(writefd); 
    /* Remove FIFOs now that we are done using them */ 
    if (unlink (FIFO1) < 0) { 
     perror("client unlink FIFO1"); 
     exit(1); 
    } 
    if (unlink (FIFO3) < 0) { 
     perror("client unlink FIFO3"); 
     exit(1); 
    } 
    exit(0); 
} 
+0

爲什麼'goto loop'?如果你想退出一個循環,你應該使用'break'。 – 2013-03-13 09:57:33

+0

另外,爲什麼使用'mknod'作爲第一個FIFO? – 2013-03-13 10:00:25

+0

我想退出循環我希望它允許進程儘可能多地輸入行 – 2013-03-13 10:11:35

回答

3

如果我理解正確的話,你想這兩個程序是非阻塞,即它們應該能夠從中讀取來自管道的用戶

如果是這樣的話,我建議你看看系統調用select。它可以用來輪詢來自任意文件描述符的輸入。

你可以做類似下面的僞代碼:

while (1) 
{ 
    /* Poll for input */ 
    select(...); 

    if (is_pipe_readable()) 
     read_from_pipe_and_print_to_stdout(); 
    else if (is_stdin_readable()) 
     read_from_stdin_and_write_to_pipe(); 
} 

注意,當它被關閉的文件描述符變爲可讀。因此,如果管道的寫入端關閉,則讀取端變爲可讀,read返回零。

+2

也調查終端模式(熟和生)。通常情況下,終端一次只發出一行(並且您仍然使用fgets)。這聽起來像你想要一次有1個字符,這意味着選擇原始模式並使用讀取來獲得任何可用的選擇時指示文件描述符準備好讀取。 – patthoyts 2013-03-13 11:09:22

+0

我想要做的事情是,因爲我寫在過程1。它顯示在過程1和過程2上,反之亦然。 – 2013-03-13 11:39:45

+0

@AmberAslam你想一次發送一個角色?這種輪詢方法仍然可以使用,一次只能讀/寫一個字符。 – 2013-03-13 11:41:24