system V IPC (创建消息队列 进行客户端服务端交互)

ipc是进程间通信机制,由共享内存,信号量和消息队列组成,三种方法有相同的特点。

标识符:每个ipc结构都又一个唯一的引用标识符,但是标识符是在不同的ipc结构不同,在一个结构内,消息队列,信号量,共享内存之间标识符可能一样。

关键字:通过不同的ipc创建方法(msgget,semget,shmget)会制定一个关键字,key_t(长整型)由内核转变标识符。ftok可以将一个路径和项目id转换为关键字。

创建消息队列

//
//  main.cpp
//  IPC
//
//  Created by 蓝猫 on 2018/11/19.
//  Copyright © 2018年 蓝猫. All rights reserved.
//
#include <stdio.h>
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
using namespace std;
int main(int argc, const char * argv[])
{
    int qid;
    key_t key;
    key=ftok(*(argv), 'a');
    if(key<0)
    {
        cout<<"获取队列键值失败"<<endl;
        exit(0);
    }
    qid=msgget(key,IPC_CREAT|0666);
    if(qid<0)
    {
        cout<<"创建队列失败"<<endl;
        exit(0);
    }
    else
    {
        cout<<"创建队列成功"<<endl;
    }
    return 0;
}

 建立消息队列进行客户端服务端通信

键值设置为1234

客户端

//
//  main.cpp
//  Client
//
//  Created by 蓝猫 on 2018/11/20.
//  Copyright © 2018年 蓝猫. All rights reserved.
//

#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <memory>
//#include <error.h>
using namespace std;
typedef struct my_msg
{
    long int my_msg_type;//数据类型
    char text[BUFSIZ];//消息缓冲区大小
}msgbuf;
class Client
{
private:
    int runningflag;//运行标志
    int msgid;//消息标志服
public:
    Client();//构造方法
    void SendMsg();//客户端信息发送
    void str_char(string s,char *text);
};
Client::Client()
{
    runningflag=1;
    
    msgid=msgget((key_t)1234, IPC_CREAT|0666);//关键字值设置1234 权限666
    if(msgid==-1)
    {
        cout<<"create error"<<endl;
        exit(1);
    }
    else
    {
        cout<<"create message queue sucess!"<<endl;
    }
}
void Client::SendMsg()
{
    //msgbuf msg;
    while (runningflag)
    {
        msgbuf msg;
        cout<<"请输入想要发送的信息"<<endl;
        //string temp;
        //cin>>temp;
        //str_char(temp, msg.text);
        fgets(msg.text, BUFSIZ, stdin);
        cout<<msg.text<<endl;
        if(msgsnd(msgid, (void*)&msg, BUFSIZ, 0)==-1)
        {
            perror("send failed\n");
            exit(1);
        }
        else
        {
            cout<<"send success!"<<endl;
        }
        if(strncmp(msg.text, "end", 3)==0)
        {
            runningflag=0;
        }
    }
}
void Client::str_char(string s,char *text)//字符串和char*的转换
{
    text=(char*)s.data();
}
int main(int argc, const char * argv[])
{
    cout<<"客户端程序"<<endl;
    shared_ptr<Client> cli=make_shared<Client>();
    cli->SendMsg();
    return 0;
}

 服务器端

//
//  main.cpp
//  Server
//
//  Created by 蓝猫 on 2018/11/20.
//  Copyright © 2018年 蓝猫. All rights reserved.
//

#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <memory>
//#include <error.h>
using namespace std;
typedef struct my_msg
{
    long int my_msg_type;//数据类型
    char text[BUFSIZ];//消息缓冲区大小
}msgbuf;
class Server
{
private:
    int runningFlg;
    int msgid;
    long int msg_to_receive;
public:
    Server();
    void GetMsg();
};
Server::Server():runningFlg(1),msg_to_receive(0)
{
    msgid=msgget((key_t)1234, 0666|IPC_CREAT);
    if(msgid==-1)
    {
        cout<<"create error"<<endl;
        exit(1);
    }
    else
    {
        cout<<"create message queue sucess!"<<endl;
    }
}
void Server::GetMsg()
{
    while (runningFlg)
    {
        msgbuf msg;
        if(msgrcv(msgid, (void *)&msg, BUFSIZ, msg_to_receive, 0)==-1)
        {
            perror("receive failed\n");
            exit(1);
        }
        else
        {
            cout<<"receive success!"<<endl;
        }
        cout<<"接收的信息是:"<<msg.text<<endl;
        if(strncmp(msg.text, "end", 3)==0)
        {
            runningFlg=0;
        }
    }
    if(msgctl(msgid, IPC_RMID, 0)==-1)
    {
        perror("删除消息队列失败\n");
        exit(1);
    }
    
}
int main(int argc, const char * argv[])
{
    cout<<"服务端程序"<<endl;
    shared_ptr<Server> cli=make_shared<Server>();
    cli->GetMsg();
    return 0;
}

结果

猜你喜欢

转载自blog.csdn.net/BJUT_bluecat/article/details/84248954