您的位置:首页 > 运维架构 > Linux

Linux 管道通信 客户端与服务器通信

2014-08-24 19:53 246 查看
实现多个客户端之间的通信(进程之间的通信),服务器作为中转站,并提示哪个客户端上线

运行命令

mkfifo fifo

gcc server.c -o server

gcc client.c -o client

./server fifo

在开三个终端分别输入./client fifo 表示三个客户端

服务器代码

/*************************************************************************
> File Name: server.c
> Author: yang
> Mail:826123027@qq.com
> Created Time: 2014年08月23日 星期六 18:59:46
************************************************************************/

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
typedef struct tag{//储存进程信息
int s_id;//客户端的进程号
int s_fd;//向客户端发送信息的标识符
int s_flag;//标记是否在server的队列里面
}USR,*pUSR;
int main(int argc,char *argv[]){
int fd_server;
USR ulist[1024];
memset(ulist,0,sizeof(ulist));
int nret;
char buf[1024];
fd_server=open(argv[1],O_RDONLY);//之前就建好的管道,负责客户端向server发送 三种信息分别为1)在线 2)客户发送的消息 3)下线
if(fd_server==-1){
perror("error");
exit(1);
}
fd_set bak_set,ready_set;//bak_set先备份一下
FD_ZERO(&bak_set);
FD_SET(fd_server,&bak_set);
struct timeval tm;//间隔时间
while(1){
tm.tv_sec=0;
tm.tv_usec=1000;
ready_set=bak_set;
nret=select(fd_server+1,&ready_set,NULL,NULL,&tm);//检测进程中有几个向server发送信息
if(nret==0)
continue;
if(FD_ISSET(fd_server,&ready_set)){//检测标识符fd_server是否发送信息
memset(buf,0,1024);
if(read(fd_server,buf,1024)==0){
continue;
}
else{
if(strncmp(buf,"on",2)==0){//检测穿来的信息是不是上线信息
int pid;
char pipename[32]="";
sscanf(buf+3,"%d",&pid);
printf("%d on \n",pid);
sprintf(pipename,"%d.fifo",pid);
int index;
for(index=0;index<1024;index++)
if(ulist[index].s_flag==0)
break;
if(index==1024)
printf("full!\n");
else{
ulist[index].s_flag=1;
ulist[index].s_id=pid;
ulist[index].s_fd=open(pipename,O_WRONLY);
}

}
else if(strncmp(buf,"off",3)==0){//是不是下线信息
int pid;
sscanf(buf+3,"%d",&pid);
char pipename[32]="";
sprintf(pipename,"%d.fifo",pid);
printf("%d off\n",pid);
int index;
for(index=0;index<1024;index++){
if(ulist[index].s_id==pid){
ulist[index].s_flag=0;
ulist[index].s_id=0;
close(ulist[index].s_fd);
break;
}
}
}
else {//其他消息
int index;
for(index=0;index<1024;index++){
if(ulist[index].s_flag==1)
write(ulist[index].s_fd,buf,strlen(buf));
}
}
}
}
}
}


客户端代码

/*************************************************************************
> File Name: client.c
> Author: yang
> Mail:826123027@qq.com
> Created Time: 2014年08月23日 星期六 19:54:40
************************************************************************/

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
int main(int argc,char *argv[]){
char pipename[32]="";
int fd_send,fd_recv;
sprintf(pipename,"%d.fifo",getpid());
if(-1==mkfifo(pipename,0666)){//根据这个名字建管道
perror("mkfifo");
exit(1);
}
char msg[1024]="";
sprintf(msg,"on %d\n",getpid());
fd_send=open(argv[1],O_WRONLY);
if(fd_send==-1){
perror("open");
exit(1);
}
write(fd_send,msg,strlen(msg));//发送上线信息
fd_recv=open(pipename,O_RDONLY);//从这个新管道读
if(fd_recv==-1){
perror("open client");
exit(1);
}
if(fork()==0){//另开辟进程用来读
close(fd_send);
while(memset(msg,0,1024),read(fd_recv,msg,1024)>0){
printf("msg>>:");
write(1,msg,strlen(msg));
}
close(fd_recv);
exit(1);
}
//	close()用来写信息
while(memset(msg,0,1024),fgets(msg,1024,stdin)!=NULL){
write(fd_send,msg,strlen(msg));
}
memset(msg,0,1024);//发送下线信息
sprintf(msg,"off %d\n",getpid());
write(fd_send,msg,strlen(msg));
close(fd_send);
close(fd_recv);
wait(NULL);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: