如何从多个命名管道接收消息?

Posted

技术标签:

【中文标题】如何从多个命名管道接收消息?【英文标题】:How Can I receive messages from more than one named pipes? 【发布时间】:2015-05-29 11:21:18 【问题描述】:

我必须在我的代码中使用先进先出。

我使用 sock 来接受新客户。我为每个客户创建新线程来向他发送和接收消息。

在线程函数中,我使用 fifo 向另一个进程发送和接收消息,这是我的代码:

 int s_to_c=open(myfifo1,O_WRONLY);
 int c_to_s=open(myfifo2,O_RDONLY);

 char echoBuffer[RCVBUFSIZE];           
 int recvMsgSize; 

 for(;;)
    
     bzero(echoBuffer,RCVBUFSIZE);              
     read(c_to_s, echoBuffer, RCVBUFSIZE);  
     write(sock, echoBuffer, strlen(echoBuffer));
     bzero(echoBuffer,RCVBUFSIZE);

     read(sock, echoBuffer, RCVBUFSIZE);
     write(s_to_c,echoBuffer,strlen(echoBuffer));


close(c_to_s);
close(s_to_c);
close(sock);

在另一边(另一个进程)我的代码:

int s_to_c=open(myfifo1,O_RDONLY);
int c_to_s=open(myfifo2,O_WRONLY);

char echoBuffer[RCVBUFSIZE];     
int recvMsgSize;
for(;;)

    bzero(echoBuffer,RCVBUFSIZE);
    fgets(echoBuffer,RCVBUFSIZE,stdin);
    echoBuffer[strlen(echoBuffer)-1]='\0';

    write(c_to_s, echoBuffer, strlen(echoBuffer));

    bzero(echoBuffer,RCVBUFSIZE);

    read(s_to_c, echoBuffer, RCVBUFSIZE);
    printf("%s\n", echoBuffer);

我的问题是在这个过程中:s_to_cc_to_s 总是取值(3,4)。

所以第一个客户端正确连接发送和接收他的消息。

但是当第二个连接时第一个客户端被禁用。并且第二个客户端的消息发送和接收到两个进程。

我能帮上忙吗?例如我应该使用标签吗??

【问题讨论】:

在您的实际代码中,您确实有错误检查吗?并且文件描述符获得什么值是无关紧要的,文件描述符3(例如)与另一个进程中的文件描述符3不同。你总是得到相同的只是意味着你在打开管道之前没有使用任何其他描述符。 对不起,我不明白你的意思。我的代码为第一个客户端正确执行。在服务器中,我打印值:sock=4。 s_to_c=6。 c_to_s=7。在这个过程中,我有这个值:s_to_c=3。 c_to_s=4. 就像我说的,描述符数字真的无关紧要,不用担心。 我的想法可能比较复杂,不专业。我想在服务器 pc 中为每个新客户端打开新窗口(新进程),所以我必须在客户端和服务器之间使用套接字。以及服务器代码和新终端窗口之间的fifi 【参考方案1】:

select() 允许您检查文件描述符的状态(在您的情况下是连接到管道的那些)。当select() 返回时,它会告诉您哪些管道有数据要处理。这样,您可以监控服务器进程中的许多管道。

客户端进程将始终将文件描述符 3 和 4 用于管道,因为它们是 stdio 之后的第一个空闲的 (0=stdin, 1=stdout, 2=stderr)。所以这是正确的。

如果您在服务器上也看到 3 和 4 的组合,那么您在创建管道的代码中存在错误,而不是在您使用它们的地方。

如果您使用 Linux,有一种简单的方法可以查看文件描述符所连接的内容:查看 /proc/PID/fd/(将 PID 替换为您要检查的进程的 ID)或使用 lsof -n -p PID(显示还有很多其他的东西,比如加载的共享库)。

【讨论】:

对不起,这不是我要找的。为每个新客户端创建新线程。在这些情况下,选择无法帮助我。我在考虑每个拖车边的标签吗?这对我有帮助吗? 或者我必须使第二个过程中的值不等于(3,4)

以上是关于如何从多个命名管道接收消息?的主要内容,如果未能解决你的问题,请参考以下文章

保护 WCF 使用的命名管道

可能的竞争条件,来自多个 tee 接收者的管道输出在 BASH 脚本中的命名管道上无序到达

Linux进程间通信——使用消息队列

未在 Tornado 中接收所有命名管道输出

命名管道客户端可以写入多个实例吗?

尝试编写命名管道时如何修复“Broken Pipe”错误?