免费注册 查看新帖 |

Chinaunix

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

关于mkfifo+select的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-14 14:45 |只看该作者 |倒序浏览
环境:RedHat Enterprise Linux AS 4
服务端代码如下(svr.c):
#include <fcntl.h>
#include <sys/select.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

#define TMOUT_SEC 5
int
mkfifo_by_proc()
{
&nbsp;&nbsp;&nbsp;&nbsp;int fd;
&nbsp;&nbsp;&nbsp;&nbsp;char name[44];

&nbsp;&nbsp;&nbsp;&nbsp;sprintf( name,"myfifo", getenv( "HOME" ) );
&nbsp;&nbsp;&nbsp;&nbsp;unlink( name );
&nbsp;&nbsp;&nbsp;&nbsp;mkfifo( name, 0666 );
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;fd = open( name, O_RDONLY );

&nbsp;&nbsp;&nbsp;&nbsp;return fd;
}
main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int         ret;
&nbsp;&nbsp;&nbsp;&nbsp;int         procfd;
&nbsp;&nbsp;&nbsp;&nbsp;char        buff[512];
&nbsp;&nbsp;&nbsp;&nbsp;fd_set      readfds;
&nbsp;&nbsp;&nbsp;&nbsp;int         maxfd;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval tmout;

&nbsp;&nbsp;&nbsp;&nbsp;procfd = mkfifo_by_proc();

&nbsp;&nbsp;&nbsp;&nbsp;while( 1 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_ZERO( &readfds );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_SET( procfd,  &readfds );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmout.tv_sec = TMOUT_SEC;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmout.tv_usec = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = select( 1024, &readfds, NULL, NULL, &tmout );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( -1 == ret && EINTR == errno ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret < 0 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "select error: %d", errno );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( ret == 0 ) {   /* time out */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;   /* SERVER CONTINUE */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( FD_ISSET( procfd, &readfds ) ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( read( procfd, buff, 1024 ) < 0 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "read err[%d]", errno );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep( 1 );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "buff=[%s]\n", buff );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//    sleep( 1 );

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;close( procfd );

&nbsp;&nbsp;&nbsp;&nbsp;exit ( 0 );
}


客户端代码如下(cli.c):
#include <fcntl.h>
#include <sys/select.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

#define TMOUT_SEC 5
main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int         ret;
&nbsp;&nbsp;&nbsp;&nbsp;int         procfd;
&nbsp;&nbsp;&nbsp;&nbsp;char        buff[512];
&nbsp;&nbsp;&nbsp;&nbsp;fd_set      writefds;
&nbsp;&nbsp;&nbsp;&nbsp;int         maxfd;
&nbsp;&nbsp;&nbsp;&nbsp;int         wrfd;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval tmout;

&nbsp;&nbsp;&nbsp;&nbsp;char file_name[256];
&nbsp;&nbsp;&nbsp;&nbsp;strcpy( file_name, "myfifo" );

&nbsp;&nbsp;&nbsp;&nbsp;wrfd = open( file_name, O_WRONLY );
#if 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( write( wrfd, file_name, strlen(file_name) ) < 0 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "write err[%d]", errno );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep( 1 );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "Send msg=[%s]", buff );
#endif
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_ZERO( &writefds );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_SET( wrfd,  &writefds );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmout.tv_sec = TMOUT_SEC;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmout.tv_usec = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = select( wrfd+1, NULL,&writefds, NULL, &tmout );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( -1 == ret && EINTR == errno ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret < 0 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "select error: %d", errno );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( ret == 0 ) {   /* time out */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;   /* SERVER CONTINUE */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( FD_ISSET( wrfd, &writefds ) ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( write( wrfd, file_name, strlen(file_name) ) < 0 ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "write err[%d]", errno );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep( 1 );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "Send msg=[%s]", buff );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep( 1 );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_CLR( wrfd, &writefds );

&nbsp;&nbsp;&nbsp;&nbsp;close( wrfd );

&nbsp;&nbsp;&nbsp;&nbsp;exit ( 0 );
}


cc -o cli cli.c
cc -o svr svr.c
问题:
当我用向myfifo写入数据时,用客户端cli向svr发送消息,或者直接使用shell命令:echo MSG > myfifo
服务端的结果都是无限循环的输出结果,比如我发送的消息是字符串为:MSG,服务端屏幕循环输出:buf=MSG

请各位老师支招,看下程序是哪里的原因?mkfifo? or select?

论坛徽章:
0
2 [报告]
发表于 2009-05-14 14:54 |只看该作者
if( FD_ISSET( procfd, &readfds ) ) {
            if( read( procfd, buff, 1024 ) < 0 ) {
                printf( "read err[%d]", errno );
                sleep( 1 );
                continue;
            }
            
            printf( "buff=[%s]\n", buff );
        }
这里错了,你好好想想,select的返回值都怎么说的

论坛徽章:
0
3 [报告]
发表于 2009-05-14 15:53 |只看该作者
楼上请指教下。select 一直返回1,说明有一个句柄是可读的。
改了下read参数,我传输字符串长度为4,所以read( procfd, buff, 4 ),问题还是存在的。

论坛徽章:
0
4 [报告]
发表于 2009-05-14 16:00 |只看该作者
客户端关了read返回0
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP