免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1708 | 回复: 3
打印 上一主题 下一主题

[C] 服务器客户端 与 有名管道 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-09 12:58 |只看该作者 |倒序浏览
大大们好,小菜刚开始linux下的编程。参考资料是APUE

我用有名管道实现了  一个服务端与多个客户端 通信的模型。
自己感觉思路是没有多少问题的。

服务端ctld <------------------> 客户端的child server

---------------------------------
参考的模型见附件

麻烦大大们看看我写的代码吧,mkfifo函数已经成功,可以在相应的目录看到已经生成的文件。现在的问题是,程序运行后堵塞在某个地方,无法继续运行下去

多谢大大们了
-------------------------------------------
head.h




#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/limits.h>
#include <string.h>
#include <stdio.h>
#define B_SIZE PIPE_BUF
const char *CTLD = "/tmp/ctld";
typedef struct message
{ char fifo_name[B_SIZE];
     char data[B_SIZE];
} my_msg;

--------------------------------------------
child_srv.c:

#include "head.h"

int main(){
int ctld_fifo,s_fifo;
  my_msg msg;
memset(&msg,'\0',sizeof(msg));

sprintf(msg.fifo_name,"/tmp/fifo%8d",getpid());

umask(0);
if (mkfifo(msg.fifo_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))
   {
       perror("mkfifo srv";
       exit(1);
   }
if( s_fifo = open(msg.fifo_name,O_RDONLY) < 0 ) {

unlink(msg.fifo_name);
perror("open child srv";
}

if( ctld_fifo = open(CTLD,O_WRONLY)  < 0 ) {
perror("open ctld";
}
  
//先传递子服务程序的描述符
write(ctld_fifo, &msg, sizeof(msg));
printf("write srvfifo ok!\n";
while( read(s_fifo, &msg, sizeof(msg)) > 0){
//ctld传过来的数据

printf("\n\nsrv received data from ctld: %s\n",msg.data);
   //通过ctld_fifo传回数据
  strcpy(msg.data,"data in srv  to ctld\n\n";
  write(ctld_fifo, &msg, sizeof(msg));
printf("after database handle data!\n";
}
}

----------------------------------------------

ctld.c:

#include "head.h"
void
clr_fl(int fd, int flags)
{   int val;
    if ((val = fcntl(fd, F_GETFL, 0)) == -1)
    { perror("fcntl error";
        exit(1);
    }
    val &= ~flags; /* turn flags off */
    if (fcntl(fd, F_SETFL, val) == -1)
    {  perror("fcntl error";
       exit(1);
    }
}
int main(){
int s_fifo,ctld_fifo;
  my_msg msg;
//printf("before mkfifo\n";

//////下面部分为处理ctld部分的fifo,可以略去不看,只要知道生成了fifo就可以
unlink(CTLD);
umask(0);
   if (mkfifo(CTLD, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))
   {
       perror("mkfifo ctld";
       exit(1);
   }

if ( (ctld_fifo = open(CTLD, O_RDONLY | O_NONBLOCK)) < 0  )perror("open error");
if ( open(CTLD, O_WRONLY) < 0 ) perror("open error");
clr_fl(ctld_fifo, O_NONBLOCK);
//////

printf("After mkfifo ctld_fifo");
//////先获取子服务程序的描述符
if( read(ctld_fifo, &msg, sizeof(msg)) < 0 ) perror("read child srv fd error");
printf("read ctldfifo ok!\n");

if (( s_fifo = open(msg.fifo_name, O_WRONLY)) == -1 ) perror("open child srv error");
    while(1){
  
//填充msg.data数据域

strcpy(msg.data,"\n\ninput :ctld's data !!!\n");
write(s_fifo, &msg, sizeof(msg));

//从ctld_fifo读取child srv传来的数据
  while( read(ctld_fifo, &msg, sizeof(msg)) > 0){

//将msg.data显示
printf("ctld received data:%s\n\n",msg.data);
sleep(10);

}
}
//close(s_fifo);


}

[ 本帖最后由 wpclub 于 2009-4-9 13:23 编辑 ]

未命名.JPG (17.84 KB, 下载次数: 14)

服务器_客户端 模型 描述

服务器_客户端 模型 描述

论坛徽章:
0
2 [报告]
发表于 2009-04-09 13:07 |只看该作者
大大们帮帮忙吧,小菜谢谢了

论坛徽章:
0
3 [报告]
发表于 2009-04-09 14:07 |只看该作者
没人回答

论坛徽章:
0
4 [报告]
发表于 2009-04-09 22:41 |只看该作者
if( s_fifo = open(msg.fifo_name,O_RDONLY) < 0 )
client阻塞在此处,因为没有进程open这个有名管道for write.

In the normal case (O_NONBLOCK not specified), an open for read-only blocks until some other process opens the FIFO for writing. Similarly, an open for write-only blocks until some other process opens the FIFO for reading.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP