我正在嘗試使用「使用命名管道的進程間通信簡介 - 使用命名管道的全雙工通信」,link;特別是fd_server.c
(包括如下供參考)Linux C:具有獨立讀寫命名管道的「交互式會話」?
這是我的信息,並編譯行:
:~$ cat /etc/issue Ubuntu 10.04 LTS \n \l :~$ gcc --version gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 :~$ gcc fd_server.c -o fd_server
fd_server.c
創建兩個命名管道,一個用於讀取,一個用於寫入。什麼人可以做的,就是:在一個終端,運行在服務器和讀取(通過cat
)其寫入管道:
:~$ ./fd_server & 2>/dev/null [1] 11354 :~$ cat /tmp/np2
,並在另一個,寫(使用echo)到服務器的讀取管道:
:~$ echo "heeellloooo" > /tmp/np1
回到第一終端,人們可以看到:
:~$ cat /tmp/np2 HEEELLLOOOO 0[1]+ Exit 13 ./fd_server 2> /dev/null
我想什麼做的,是讓不大不小的「互動」(或「殼」類似的)會議;也就是說,服務器像往常一樣運行,但不是運行cat
和echo
,我想使用類似的屏幕。我的意思是,屏幕可以稱爲screen /dev/ttyS0 38400
,然後它進行一種交互式會話,在終端中鍵入的內容將傳遞到/dev/ttyS0
,並將其響應寫入終端。現在,當然,我不能使用screen
,因爲在我的情況下,程序有兩個單獨的節點,並且據我所知,screen
只能指一個。
如何在這種情況下實現這種「交互式」會話(使用兩個獨立的讀/寫管道)?下面
代碼:
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <fullduplex.h> /* For name of the named-pipe */
#define NP1 "/tmp/np1"
#define NP2 "/tmp/np2"
#define MAX_BUF_SIZE 255
#include <stdlib.h> //exit
#include <string.h> //strlen
int main(int argc, char *argv[])
{
int rdfd, wrfd, ret_val, count, numread;
char buf[MAX_BUF_SIZE];
/* Create the first named - pipe */
ret_val = mkfifo(NP1, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
ret_val = mkfifo(NP2, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
/* Open the first named pipe for reading */
rdfd = open(NP1, O_RDONLY);
/* Open the second named pipe for writing */
wrfd = open(NP2, O_WRONLY);
/* Read from the first pipe */
numread = read(rdfd, buf, MAX_BUF_SIZE);
buf[numread] = '0';
fprintf(stderr, "Full Duplex Server : Read From the pipe : %sn", buf);
/* Convert to the string to upper case */
count = 0;
while (count < numread) {
buf[count] = toupper(buf[count]);
count++;
}
/*
* Write the converted string back to the second
* pipe
*/
write(wrfd, buf, strlen(buf));
}
編輯:
權,只是爲了澄清 - 看來我發現了一個document討論非常類似的東西,它是 - 腳本的修改有(」 對於例如,下面的腳本配置設備並啓動一個後臺進程,將從串行設備接收到的所有數據複製到標準輸出...「)爲以下程序:
# stty raw #
(./fd_server 2>/dev/null;)&
bgPidS=$!
(cat < /tmp/np2 ;)&
bgPid=$!
# Read commands from user, send them to device
echo $(kill -0 $bgPidS 2>/dev/null ; echo $?)
while [ "$(kill -0 $bgPidS 2>/dev/null ; echo $?)" -eq "0" ] && read cmd; do
# redirect debug msgs to stderr, as here we're redirected to /tmp/np1
echo "$? - $bgPidS - $bgPid" >&2
echo "$cmd"
echo -e "\nproc: $(kill -0 $bgPidS 2>/dev/null ; echo $?)" >&2
done >/tmp/np1
echo OUT
# Terminate background read process - if they still exist
if [ "$(kill -0 $bgPid 2>/dev/null ; echo $?)" -eq "0" ] ;
then
kill $bgPid
fi
if [ "$(kill -0 $bgPidS 2>/dev/null ; echo $?)" -eq "0" ] ;
then
kill $bgPidS
fi
# stty cooked
所以,保存腳本說starter.sh
和調用它,與下一屆會議的結果:
$ ./starter.sh
0
i'm typing here and pressing [enter] at end
0 - 13496 - 13497
I'M TYPING HERE AND PRESSING [ENTER] AT END
0~�.N=�(�~� �����}����@������~� [garble]
proc: 0
OUT
這是我會叫「交互會話」(忽略調試語句) - 服務器等待我輸入命令;它在接收到一個命令後給出它的輸出(在這種情況下,它在第一個命令之後退出,起始腳本也一樣)。除此之外,我想沒有緩衝輸入,但逐字發送(這意味着上面的會話應該在第一次按鍵後退出,並且只打印出單個字母 - 這是我期望raw有幫助,但它不是:它只是殺死反應既輸入和按Ctrl - ç :))
我只是遊蕩,如果已經有一個現有的命令(對於串行設備類似於screen
,我猜)會接受兩個這樣的命名管道作爲參數,並通過它們建立像會話那樣的「終端」或「shell」;或者我將不得不使用上面的腳本和/或編程自己的「客戶端」,它將起到終端的作用。
使用Ctrl + K將代碼縮進四個空格,這將創建一個語法高亮的代碼塊。我爲你做了,停止編輯。 ;-) – 2010-05-06 13:12:45
謝謝,約翰Kugelman,建議和編輯:) – sdaau 2010-05-06 13:18:13