[英]writing to stdin of another program/reading from stdout of another program in c
這是一個家庭作業問題。 我有3個程序A,B和C,它們不是父/子進程,而是單獨的程序。 B必須向A的stdin寫一條消息(“Hello”)並從C的stdout讀取另一條消息(“Hello”)。我應該使用哪個概念來實現它? 我環顧了一段時間但我找不到合適的東西。 我以為我應該使用FIFO,但我無法重定向管道。 我可以將FIFO與FIFO一起使用嗎? 如果有,怎么樣? 這不是作業本身,而是它應該的工作方式。 然后我會在其上實現其他的東西。 (我可以發布我的fifo基本代碼,如果是這樣的話,現在就不要這樣做,因為我不確定)
如果我誤解了這個問題,請告訴我。
假設你創建程序A
, B
和C
以編程方式,您可以使用man 1 mkfifo
或man 3 mkfifo
來創建命名管道。
然后,每個進程都會open(2)
它們並根據需要使用dup2(2)
。
例如,程序A
可以像這樣重定向它的stdout
:
int fifo = open("fifo_1", O_WRONLY);
dup2(fifo, 1);
或者程序B
可以像這樣重定向它的stdin
和stdout
:
int fifo_in = open("fifo_1", O_RDONLY);
int fifo_out = open("fifo_2", O_WRONLY);
dup2(fifo_in, 0);
dup2(fifo_out, 1);
或者你需要的任何其他東西
我修改了這段代碼@chrk解釋道。 這是“高級Unix編程”一書中的FIFO示例。 一個簡單的服務器客戶端示例。 客戶端向服務器發送三個較低的字符串,服務器使它們成為高級通信並通過FIFO發送回客戶端(“fifo#clientpid”是客戶端的fifo的名稱)。 客戶端將它們打印到stdout。 所以我修改它的方式是在從客戶端收到消息后,服務器將高級字符串寫入客戶端的STDINT。 客戶端從STDINT讀取它們並打印到它的標准輸出。 它按我的預期工作。 謝謝你的幫助。 首先,我以錯誤的方式實施。 在chrk的代碼的幫助下,我再次寫了它。 這是代碼:
客戶的輸出
client 2941 started
client 2941: applesauce --> APPLESAUCE
client 2941: tiger --> TIGER
client 2941: mountain --> MOUNTAIN
Client 2941 done
服務器:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}
#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE 0664
struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};
int main()
{
int fd_server, fd_client, i;
ssize_t nread;
struct simple_message msg;
char fifo_name[100];
printf("server started\n");
if (mkfifo(SERVER_FIFO_NAME, PERM_FILE) == -1 && errno != EEXIST)
{perror("can't make fifo"); exit(errno); }
ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_RDWR), "cant open fd_server" )
while (1)
{
ec_neg1( nread = read(fd_server, &msg, sizeof(msg)), "can't read from fd_server")
if (nread == 0) {
errno = ENETDOWN;
perror("nread == 0"); exit(errno);
}
for (i = 0; msg.sm_data[i] != '\0'; i++)
msg.sm_data[i] = toupper(msg.sm_data[i]);
make_fifo_name(msg.sm_clientpid, fifo_name, sizeof(fifo_name));
ec_neg1( fd_client = open(fifo_name, O_WRONLY), "can't open fifo_name" )
ec_neg1( write(fd_client, &msg, sizeof(msg)), "can't write to fd_client" )
ec_neg1( close(fd_client), "can't close fd_client" )
}
/* never actually get here */
ec_neg1( close(fd_server), "can't close fd_server" )
exit(EXIT_SUCCESS);
return 0;
}
int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
snprintf(name, name_max, "fifo%ld", (long)pid);
return 0;
}
客戶
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}
#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE 0664
struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};
int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
snprintf(name, name_max, "fifo%ld", (long)pid);
return 0;
}
int main()
{
int fd_server, fd_client = -1, i;
ssize_t nread;
struct simple_message msg;
char fifo_name[100];
char *work[] = {
"applesauce",
"tiger",
"mountain",
NULL
};
printf("client %ld started\n", (long)getpid());
msg.sm_clientpid = getpid();
make_fifo_name(msg.sm_clientpid, fifo_name,
sizeof(fifo_name));
if (mkfifo(fifo_name, PERM_FILE) == -1 && errno != EEXIST)
{perror("can't make fifo"); exit(errno); }
ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_WRONLY), "can't open fd_server" )
for (i = 0; work[i] != NULL; i++)
{
strcpy(msg.sm_data, work[i]);
ec_neg1( write(fd_server, &msg, sizeof(msg)),"can't write to fd_server" )
if (fd_client == -1){
ec_neg1( fd_client = open(fifo_name, O_RDWR), "can't open fifo_name" )
ec_neg1(dup2(fd_client, 0), "can't duplicate stdin")
}
ec_neg1( nread = read(0, &msg, sizeof(msg)), "can't read from fd_client" )
if (nread == 0) {
errno = ENETDOWN;
perror("nread == 0"); exit(errno);
}
printf("client %ld: %s --> %s\n", (long)getpid(),
work[i], msg.sm_data);
}
ec_neg1( close(fd_server), "can't close fd_server" )
ec_neg1( close(fd_client), "can't close fd_client" )
ec_neg1( unlink(fifo_name), "can't unlink fifo_name" )
printf("Client %ld done\n", (long)getpid());
exit(EXIT_SUCCESS);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.