一、基于select接口+有名管道的I/O 多路复用

1、注意提示点:

1、基于客户端以及服务器两端的使用

2 、对于有名管道,须注意有名管道的链接顺序,否则,可能发生死锁,或链接不成功。

3、学会select接口的使用。

2、select函数的数据结构

 #include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);void FD_CLR(int fd, fd_set *set);int  FD_ISSET(int fd, fd_set *set);void FD_SET(int fd, fd_set *set);void FD_ZERO(fd_set *set);  struct timeval {long    tv_sec;         /* seconds */long    tv_usec;        /* microseconds */};3、客户端以及服务端源代码头文件:
#include <string.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>客户端:
#include"func.h"int main(int argc,char *argv[])
{if(3!=argc){printf("error argcs!\n");return -1;}int fdr,fdw;fdr=open(argv[1],O_RDONLY);        //打开管道一的读端if(-1==fdr){perror("open1");return -1;}fdw=open(argv[2],O_WRONLY);       //打开管道二的写端if(-1==fdw){perror("open2");return -1;}printf("Now I can receive:fdr=%d,fdw=%d\n",fdr,fdw);int ret;   char buff[35];struct timeval t;t.tv_sec=3;t.tv_usec=0;fd_set fd_rd;         //只用检测读即可while(1){FD_ZERO(&fd_rd);FD_SET(fdr,&fd_rd);FD_SET(0,&fd_rd);ret=select(fdr+1,&fd_rd,NULL,NULL,&t);if(FD_ISSET(fdr,&fd_rd)){memset(buff,0,sizeof(buff));ret=read(fdr,buff,sizeof(buff));if(ret>0){printf("TWO:");puts(buff);}else{printf("byebye!\n");break;}}if(FD_ISSET(0,&fd_rd)){memset(buff,0,sizeof(buff));//puts("请输入:");ret=read(0,buff,sizeof(buff));if(ret>0){write(fdw,buff,strlen(buff)-1);}else{printf("byebyei\n");break;}}}return 0;
}服务端:#include"func.h"int main(int argc,char *argv[])
{if(3!=argc){printf("error argcs!\n");return -1;}int fdr,fdw;fdw=open(argv[1],O_WRONLY);        //打开管道一的写端if(-1==fdw){perror("open1");return -1;}fdr=open(argv[2],O_RDONLY);       //打开管道二的读端if(-1==fdr){perror("open2");return -1;}printf("fdw=%d,fdr=%d\n",fdw,fdr);char buff[30]={0};fd_set fd_rd;int ret;struct timeval t;t.tv_usec=0;while(1){  FD_ZERO(&fd_rd);FD_SET(0,&fd_rd);FD_SET(fdr,&fd_rd);t.tv_sec=30;ret=select(fdr+1,&fd_rd,NULL,NULL,&t);if(ret>0){if(FD_ISSET(0,&fd_rd)){memset(buff,0,sizeof(buff));//puts("请输入:");ret=read(0,buff,sizeof(buff));        //若果没有接到结束符,就以为一直要输入if(ret>0){write(fdw,buff,strlen(buff)-1);}else{printf("byebye!\n");break;}}if(FD_ISSET(fdr,&fd_rd)){memset(buff,0,sizeof(buff));ret=read(fdr,buff,sizeof(buff));if(ret>0){printf("ONE:");puts(buff);}}}else{printf("no fd read!\n");break;}}return 0;
}

二、融入共享内存和信号锁的 I/O多路复用的简洁版即时聊天


1、需求陈述:
       A,B 两个进程通过管道通信, 像以前的互相聊天一样, 然后 A 进程每次接收到的数据通过 A1 进程显
示( 一个新进程, 用于显示A 接收到的信息) , A 和 A1 间的数据传递采用共享内存, 对应的有一个 B1
进程, 用于显示B 进程接收到的信息。 针对 A,B 进程, 退出时采用 ctrl+c 退出, 当收到对应信号后,
自身进程能够通过信号处理函数进行资源清理, 清理后exit 退出进程。 ( A1,B1, 手动关闭即可) 。 界
面图如下。     

2、源代码

头文件:#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<string.h>
#include<signal.h>
#include<stdlib.h>typedef struct Shminfo{short flag;char buf[50];
}shminf;
男孩聊天主程序:#include"func.h"//部分定义全局变量
int sem,shmid,fdr,fdw;
shminf *p;//退出处理函数
void sighandle(int signum)
{//printf("I am in out!\n");p->flag=3;sleep(1);semctl(sem,IPC_RMID,0);shmdt(p);int handret;handret=shmctl(shmid,IPC_RMID,0);//close(fdr);//close(fdw);kill(getpid(),SIGINT);close(fdr);close(fdw);exit(0);
}int main(int argc,char *argv[])
{signal(SIGINT,sighandle);if(3!=argc){printf("error argcs!\n");return -1;}//信号量设置初始化和共享内存初始化//int sem;sem=semget(12356,1,IPC_CREAT|0600);if(-1==sem){perror("semget");return -1;}int ret;ret=semctl(sem,0,SETVAL,1);if(-1==ret){perror("semctl");return -1;}//共享内存//int shmid;shmid=shmget(10003,500,IPC_CREAT|0600);if(-1==shmid){perror("shmid");return -1;}//共享内存结构体//shminf *p;p=(shminf *)shmat(shmid,NULL,0);if(p==(shminf *)-1){perror("shmat");return -1;}p->flag=0;memset(p->buf,0,sizeof(p->buf));//初始化P 和 V 的初值struct sembuf sopp,sopv;memset(&sopp,0,sizeof(sopp));memset(&sopv,0,sizeof(sopv));sopp.sem_num=0;sopp.sem_op=-1;sopp.sem_flg=SEM_UNDO;sopv.sem_num=0;sopv.sem_op=1;sopv.sem_flg=SEM_UNDO;//管道的连接//int fdr,fdw;fdw=open(argv[1],O_WRONLY);     //打开管道一的写端if(-1==fdw){perror("open1");return -1;}fdr=open(argv[2],O_RDONLY);       //打开管道二的读端if(-1==fdr){perror("open2");return -1;}printf("fdw=%d,fdr=%d\n",fdw,fdr);char buff[30]={0};fd_set fd_rd;//int ret;//struct timeval t;//t.tv_usec=0;while(1){    FD_ZERO(&fd_rd);FD_SET(0,&fd_rd);FD_SET(fdr,&fd_rd);//t.tv_sec=30;ret=select(fdr+1,&fd_rd,NULL,NULL,NULL);//if(ret>0)//{if(FD_ISSET(0,&fd_rd)){memset(buff,0,sizeof(buff));//puts("请输入:");ret=read(0,buff,sizeof(buff));        //若果没有接到结束符,就以为一直要输入if(ret>0){memset(p->buf,0,sizeof(p->buf));semop(sem,&sopp,1);strcpy(p->buf,buff);p->flag=1;semop(sem,&sopv,1);write(fdw,buff,strlen(buff));}//else{//p->flag=3;//sleep(1);// kill(getpid(),SIGINT);// signal(SIGQUIT,sighandle);//printf("byebye!\n");//break;// signal(SIGINT,sighandle);//}}if(FD_ISSET(fdr,&fd_rd)){memset(buff,0,sizeof(buff));ret=read(fdr,buff,sizeof(buff));if(ret>0){memset(p->buf,0,sizeof(p->buf));semop(sem,&sopp,1);strcpy(p->buf,buff);p->flag=2;         //控制打印次数semop(sem,&sopv,1);//测试语句两行//printf("Girl:");//puts(buff);}else{p->flag=3;sleep(1);semctl(sem,IPC_RMID,0);shmdt(p);int handret;handret=shmctl(shmid,IPC_RMID,0);kill(getpid(),SIGINT);close(fdr);close(fdw);exit(0);//signal(SIGQUIT,sighandle);//printf("byebye!\n");//break;}}//signal(SIGQUIT,sighandle);/*}else{printf("no fd read!\n");break;}*/}return 0;
}
男孩显示窗口源代码:#include"func.h"int main()
{//连接共享内存和信号量int sem;sem=semget(12356,1,IPC_CREAT|0600);int ret;int shmid;shmid=shmget(10003,500,IPC_CREAT|0600);shminf *pshow;pshow=(shminf *)shmat(shmid,NULL,0);while(1){if(2==pshow->flag){printf("Girl:%s",pshow->buf);pshow->flag=0;}if(1==pshow->flag){printf("Boy:%s",pshow->buf);pshow->flag=0;}if(3==pshow->flag){pshow->flag=0;printf("byebye!\n");kill(getpid(),SIGINT);//  break;}}return 0;
}
女孩聊天主程序:#include"func.h"//部分全局变量
int sem,shmid,fdr,fdw;
shminf *p;//退出处理函数
void sighandle(int signum)
{//printf("I am in out!\n");p->flag=3;sleep(1);semctl(sem,IPC_RMID,0);shmdt(p);int handret;handret=shmctl(shmid,IPC_RMID,0);kill(getpid(),SIGINT);close(fdr);close(fdw);exit(0);
}
int main(int argc,char *argv[])
{signal(SIGINT,sighandle);if(3!=argc){printf("error argcs!\n");return -1;}//信号量设置初始化和共享内存初始化//int sem;sem=semget(12345,1,IPC_CREAT|0600);if(-1==sem){perror("semget");return -1;}int ret;//初始化锁的值ret=semctl(sem,0,SETVAL,1);   if(-1==ret){perror("semctl");return -1;}//共享内存// int shmid;shmid=shmget(1000,500,IPC_CREAT|0600);if(-1==shmid){perror("shmid");return -1;}// shminf *p;        //共享内存结构体//首先将flag置为0,表示初始时buff里面没消息p=(shminf *)shmat(shmid,NULL,0);if(p==(shminf *)-1){perror("shmat");return -1;}//将标志数组全置为0p->flag=0;memset(p->buf,0,sizeof(p->buf));//初始化P 和 V 的初值struct sembuf sopp,sopv;memset(&sopp,0,sizeof(sopp));memset(&sopv,0,sizeof(sopv));sopp.sem_num=0;sopp.sem_op=-1;sopp.sem_flg=SEM_UNDO;sopv.sem_num=0;sopv.sem_op=1;sopv.sem_flg=SEM_UNDO;//管道的连接//int fdr,fdw;fdr=open(argv[1],O_RDONLY);        //打开管道一的读端if(-1==fdr){perror("open1");return -1;}fdw=open(argv[2],O_WRONLY);       //打开管道二的写端if(-1==fdw){perror("open2");return -1;}printf("Now I can receive:fdr=%d,fdw=%d\n",fdr,fdw);char buff[35];//struct timeval t;//t.tv_sec=3;//t.tv_usec=0;fd_set fd_rd;          //只用检测读即可while(1){FD_ZERO(&fd_rd);FD_SET(fdr,&fd_rd);FD_SET(0,&fd_rd);ret=select(fdr+1,&fd_rd,NULL,NULL,NULL);if(FD_ISSET(fdr,&fd_rd)){memset(buff,0,sizeof(buff));ret=read(fdr,buff,sizeof(buff));if(ret>0){memset(p->buf,0,sizeof(p->buf));semop(sem,&sopp,1);strcpy(p->buf,buff);p->flag=2;           //控制打印次数semop(sem,&sopv,1);//测试语句两行//printf("Boy:");//puts(buff);}else{//printf("byebye!\n");p->flag=3;sleep(1);semctl(sem,IPC_RMID,0);shmdt(p);int handret;handret=shmctl(shmid,IPC_RMID,0);kill(getpid(),SIGINT);close(fdr);close(fdw);//signal(SIGQUIT,sighandle);//break;}}if(FD_ISSET(0,&fd_rd)){memset(buff,0,sizeof(buff));//puts("请输入:");ret=read(0,buff,sizeof(buff));if(ret>0){memset(p->buf,0,sizeof(p->buf));semop(sem,&sopp,1);strcpy(p->buf,buff);p->flag=1;semop(sem,&sopv,1);write(fdw,buff,strlen(buff));}else{//printf("byebyei\n");p->flag=3;sleep(1);kill(getpid(),SIGINT);//signal(SIGQUIT,sighandle);//break;}//else //signal(SIGINT,sighandle);}}return 0;
}
女孩显示窗口:#include"func.h"int main()
{//连接共享内存和信号量int sem;sem=semget(12345,1,IPC_CREAT|0600);int ret;int shmid;shmid=shmget(1000,500,IPC_CREAT|0600);shminf *pshow;pshow=(shminf *)shmat(shmid,NULL,0);while(1){if(1==pshow->flag){printf("Girl:%s",pshow->buf);pshow->flag=0;}if(2==pshow->flag){printf("Boy:%s",pshow->buf);pshow->flag=0;}if(3==pshow->flag){printf("byebye!");pshow->flag=0;kill(getpid(),SIGINT);}}return 0;
}

三、大文件内存映射mmap实例


源代码如下:#include <sys/mman.h>
#include <sys/types.h> //头文件
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>int main(int argc,char *argv[])
{if(3!=argc){printf("error argcs!\n");return -1;}int fd1,fd2;struct stat fd;fd1=open(argv[1],O_RDWR);fd2=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666);char *p,*p1;int ret;fstat(fd1,&fd);truncate(argv[2],fd.st_size);     //必须先有空间之后才能进行操作。//ret=fd.st_size;
//  printf("ret=%d\n",ret);//char buff[fd.st_size+1];p=(char *)mmap(NULL,fd.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd1,0);p1=(char *)mmap(NULL,fd.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd2,0);memcpy(p1,p,fd.st_size);         //memcpy - copy memory areamunmap(p,fd.st_size);munmap(p1,fd.st_size);close(fd1);close(fd2);return 0;
}

简洁版即时聊天---I/O多路复用使用相关推荐

  1. Asp.Net Mvc基于Fleck开发的多人网页版即时聊天室

    一.项目的核心说明 1.Fleck这个是实现websocket一个比较简单第三方组件,它不需要安装额外的容器.本身也就几个接口可供调用. 2.项目是基于.net framework 4.7.2 ,在v ...

  2. 【详细搭建教程】在线客服系统源码3.0防黑版,即时聊天通讯源码 带机器人,防注入 无后门

    亲测搭建环境: Linux , PHP5.6+MYSQL5.6 一.下载网站源码 源码下载:源码 二.上传网站源码 网站源码上传至空间/服务器根目录 三.导入数据库 导入aixiang.sql数据库文 ...

  3. 即时聊天IM软件集合

    IM,Instant Messenger,即时传讯的缩写.写到这里,大家可能会感到不屑一顾,聊天软件就软件呗,能有什么好说的.但是在实际生活中,就有很多人曾经问过我:什么是MSN?MSN是干吗的?那么 ...

  4. 中油即时通信电脑版_一文看懂云视频会议与即时聊天软件的差别

    进入互联网时代,便捷.高效的云视频会议受到中小企业的青睐,人们通过租赁云视频会议账号,即可在视频会议室.个人电脑.智能手机上发起远程视频会议.不过随着5G等通信网络的普及,人们基于即时聊天软件进行视频 ...

  5. Web端即时聊天项目实现(基于WebSocket)

    Web端即时聊天项目实现 项目背景  其实这个项目算是我做过的花时间最长也投入心血最多的一个项目了,当时决定开始做这个的时候我几乎什么都不会,那时我个人的情况是: JavaEE方面: 会jsp+ser ...

  6. 项目实战:仿QQ的QQ简洁版2019群聊项目

    ​ 简介: 自我熟练qt的widget的使用,熟悉使用qt的network相关模块写一个仿QQ的QQ简洁版2019群聊项目.哇伊,这是我大学之处一直想写的IM即时通讯系统的,模仿写一个QQ的项目,但是 ...

  7. springboot整合websocket实现简易版单人聊天

    websockt在作为即时通讯类的聊天方面有较多的应用,其主要的特点就是轻量,使用方便,容易快速上手,通过webscoket整合服务端,就可以实现简单的类似聊天的功能,下面说说springboot整合 ...

  8. 即时聊天工具二次开发

    突然想做一个能够通知另一台电脑消息的工具.因为是自己用,又不想大动干戈,想想不如就采用现有即时聊天软件如QQ.MSN等开发个小程序就行了.我现在也不愿意编程,能少费事就少费事. 研究了QQ的二次开发, ...

  9. 跨跃平台交流无极限——linux下如何使用即时聊天工具,跨跃平台 交流无极限——Linux下如何使用即时聊天工具(一)...

    I技应 术用与 跨跃平台交流无极限 维普资讯 http://doc.xuehai.net o n I s o f i e n t@ c n i i c o m t . L n x下如何使用即时聊天工具 ...

最新文章

  1. Tomcat集群快速入门2
  2. java中集合判空_Java中的类型安全的空集合
  3. excel实战应用案例100讲(四)-Excel玩转数据:从分析到可视化
  4. 拖拽批量上传图片如何保证 顺序_新手指南︱shopee店铺上架产品该如何操作?...
  5. 清平乐·风鬟雨鬓 [清] 纳兰性德
  6. Solr管理索引库——(十三)
  7. Python - 定制pattern的string模板(template) 具体解释
  8. LinkedHashMap与HashMap的使用比较
  9. 直播盒子源码与直播盒子APP如何对接自动发卡平台
  10. java的第一行代码
  11. Python3之日志模板
  12. arcgis中python计算面积的表达式_解析ArcGis的字段计算器(一)——数值型数据计算,从“面积计算”开始...
  13. css3实现图片划过一束光闪过效果(图片光影掠过效果)
  14. html方框打勾字段,word文档怎么输入带方框的对勾
  15. Python | 阿尔法程序的控制结构
  16. 闲山:龙的出现,没有中文字幕怎么办? 自己编程搞一个试试
  17. 程序员不愁没练手的小项目
  18. 物联网毕业设计 单片机火灾报警器设计与实现
  19. AtCoder Beginner Contest 234 G - Divide a Sequence
  20. 如何搭建数据指标体系?

热门文章

  1. 计蒜客NOIP2017提高组模拟赛(四)day1
  2. 撸表情开发过程中使用腾讯云存储的接入实例分享
  3. Jmeter文章索引贴
  4. 真机iOS SDK升级后xcode不能进行真机调试 怎么办
  5. 2013款MacBook Air装Windows7单系统
  6. PHP汉字转拼音的类
  7. 突然无法连接数据库了(解决了)
  8. 搜索算法(二)--DFS/BFS求解炸弹人问题(JAVA )
  9. 查找算法——折半查找(JAVA)
  10. android标题栏的属性,android – 属性“titleTextStyle”已经定义?