欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

fifo实现单服务器多客户端

程序员文章站 2024-03-22 16:44:05
...

费劲的折腾,好几次小细节没处理好,真是醉了,不说了

代码记录下



服务端:

//fifo(first in, first out)
//有名管道
#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <cstdlib>
using namespace std;
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define FIFO_0 "/tmp/fifo0"
const int size=256;
			struct DATA
			{
			    int nLen;   //sBuf+pid的有效长度
			    pid_t pid;
			    char sBuf[size];
			};

int server(int &readfd,int &writefd);

//server
//作用:多个客户端通过FIFO向server传来文件路径名,server返回路径名的反序


int main()
{
		//start();
    int readfd,writefd;
    cout << FILE_MODE << endl;
    unlink(FIFO_0);
    if( (mkfifo(FIFO_0,FILE_MODE) < 0 ) )
    {
        if(errno = EEXIST)
            cout << "fifo is exist!" << endl;
        else
            perror("server create FIFO_0");
    }

    readfd=open(FIFO_0,O_RDONLY,0);
    writefd=open(FIFO_0,O_WRONLY,0);
    cout << "readfd=" << readfd << endl;
    cout << "writefd=" << writefd << endl;

    server(readfd,writefd);
    return 0;
}
int fifo_ret(DATA & data);
int server(int & readfd,int & writefd)
{
    struct DATA data={0};
    size_t n=0;
    size_t len=0;
    char sBuf[256]= {0};
    while(true)
    {
        //迭代式,一个个处理
        memset(&data,0x00,sizeof(data));
        n = read(readfd,&data,sizeof(data.nLen));
        if(n <= 0)
            break;
        else if(n != sizeof(data.nLen))
        {
            perror("readfifo");
            break; 
        }
        len = data.nLen;
        if(read(readfd,&data.pid,sizeof(pid_t)) == sizeof(pid_t) && \
           len == read(readfd,data.sBuf,len))
            {
            	cout << "server:" << data.nLen << data.pid << data.sBuf << endl;
            	fifo_ret(data);
            }
    }

}
void reverse(char * from, char * to)
{
    int n=strlen(from);
    int m=n;
    for(int i=0;i < n;i++)
    {
        to[i] = from[--m];
    }
}
int fifo_ret(DATA & data)
{
		//cout << "come" << endl;
    char pathname[size]="/tmp/fifo";
    int pid=(int)data.pid;
    //strcat(pathname,itoa(pid));			ubuntu,下没有itoa
    char sBuf[256];
    memset(sBuf,0x00,sizeof(sBuf));
    sprintf(sBuf,"%d",pid);
    strcat(pathname,sBuf);
    //cout <<"pathname"<< pathname << endl;
    if(mkfifo(pathname,FILE_MODE) < 0)
    {
        if(errno == EEXIST)
            cout << pathname << "exist" << endl;
        else
        {
            perror("mkfifo pathname");
            return -1;
        }
    }
    int writefd;
    sleep(3);
    if( (writefd=open(pathname,O_WRONLY,0)) < 0)
        perror("open fifo");
    char sTmp[256]={0};
    reverse(data.sBuf,sTmp);
    cout << sTmp << endl;
    write(writefd,sTmp,strlen(sTmp));
    close(writefd);
   

}


客户端:

#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <cstdlib>
using namespace std;
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define FIFO_0 "/tmp/fifo0"  
const int size=256;

struct DATA
{
    int nLen;   //sBuf+pid的有效长度
    pid_t pid;
    char sBuf[size];
};

int main()
{
    if( (mkfifo(FIFO_0,FILE_MODE) < 0 ) )
    {
        if(errno = EEXIST)
            cout << "fifo is exist!" << endl;
        else
            perror("server create FIFO_0");
    }
    int readfd,writefd;
    char pathname[size]="/tmp/fifo";
    int pid=(int)getpid();
    char sBuf[256]={0}; 
    memset(sBuf,0x00,sizeof(sBuf));
    sprintf(sBuf,"%d",pid);
    strcat(pathname,sBuf);
    if(mkfifo(pathname,FILE_MODE) < 0)
    {
        if(errno == EEXIST)
            cout << pathname << "exist" << endl;
        else
        {
            perror("mkfifo pathname");
            return -1;
        }
    }
    //多客户端向服务端发送字符串,服务器返回反序
		writefd=open(FIFO_0,O_WRONLY,0);
		sprintf(sBuf,"%d",pid);
    char sTmp[256]={0};
    DATA data;
    while(1)	//与服务器通讯
    {
    	memset(sBuf,0x00,sizeof(sBuf));    	
    	memset(sTmp,0x00,sizeof(sTmp));
    	memset(&data,0x00,sizeof(data));
    	cout << "input:[# quit]" << endl;	
    	cin >> data.sBuf;
    	if(data.sBuf[0] == '#')
    			break;
	    data.pid=pid;
	    data.nLen=strlen(data.sBuf);
	    write(writefd,&data,data.nLen+sizeof(data.nLen)+sizeof(data.pid));
	    readfd=open(pathname,O_RDONLY,0);
    	read(readfd,sTmp,sizeof(sTmp));
    	cout << "recv:" <<sTmp << endl;
    }
    	
    close(writefd);
    close(readfd);
		unlink(pathname);
    exit(0);
}