mqd_t,发送和接收消息

时间:2012-11-16 06:11:27

标签: c++ linux qt message-passing

我正在开发一个程序,我有一个名为server的进程和几个名为client的进程,可以连接到服务器并发送消息<但由于某种原因,我的客户端将无法连接到我的服务器:

这是客户端类的头文件:

#ifndef CLIENT_H
#define CLIENT_H

#include <QString>
#include <string>
#include <QByteArray>
#include <mqueue.h>
#include <iostream>
#include "serveredialog.h"
#include "badudialog.h"
#include "../src/messages.h"

class Client
{
public:
    Client();
    void init(QString name);
    void sendMessage(QString mess);
private:
    char *myMailboxName, buf[MSG_SIZE];
    struct mq_attr attr;
    mqd_t mq_ownBox, mq_centralBox;

};

#endif // CLIENT_H

这是客户端cpp文件:

#include "Client.h"

using namespace std;

Client::Client()
{
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = MSG_SIZE;
    attr.mq_flags = 0;
}

void Client::init(QString name)
{
    //Convert name into char*
    QByteArray byteArray = name.toUtf8();
    char str1[40];
    const char* tempr = byteArray.constData();
    strncpy(str1, tempr, sizeof(str1));
    myMailboxName = str1;

    //Create temp box to check if name available
    string tempS = myMailboxName;
    tempS += "new";
    const char* tempr1 = tempS.data();
    mq_unlink(tempr1);
    mq_ownBox = mq_open(tempr1, O_RDONLY | O_CREAT, S_IRWXU, &attr);
    mq_centralBox = mq_open(CENTRALBOX, O_RDWR);

    //Tell server that you are ready
    string tempS1 = str1;
    string tempS2 = "started:" + tempS1;
    const char* tempr2 = tempS2.data();
    sprintf(buf, tempr2);
    int tempI = mq_send(mq_centralBox, buf, strlen(buf), 0);
    cout << tempI;
    //Check for success
    if(tempI){
        ServerEDialog sd;
        sd.setModal(true);
        sd.exec();
    }
    else
    {
        //If success, wait for response fromserver
        while(1)
        {
            int tempI2 = mq_receive(mq_ownBox, buf, MSG_SIZE, 0);
            if(tempI2 != -1)
            {
                break;
            }
        }
        QString tempS3 = buf;

        //if invalid show error, otherwise create permanent mailbox
        if(tempS3 == "invalidname")
        {
            BadUDialog bd;
            bd.setModal(true);
            bd.exec();
        }
        else
        {
            mq_unlink(myMailboxName);
            mq_ownBox = mq_open(myMailboxName, O_RDONLY | O_CREAT, S_IRWXU, &attr);
        }
    }
}

void Client::sendMessage(QString mess)
{

}

这是我的服务器头文件:

#ifndef SERVER_H
#define SERVER_H

#include <QString>
#include <mqueue.h>
#include <QVector>
#include <QStringList>
#include <iostream>
#include "../src/messages.h"

class Server : public QObject
{
    Q_OBJECT
public:
    Server();
    void start();
private:
    void join(QString name);
    char buf[MSG_SIZE], msgSend[MSG_SIZE];
    QVector<mqd_t> mq_external;
    QVector<QString> users;
    mqd_t mq_central;
    struct mq_attr attr;


signals:
    void joined(QString name);

};

#endif // SERVER_H

这是我的服务器cpp文件:

#include "Server.h"

using namespace std;

Server::Server()
{
}

void Server::start(){

    attr.mq_maxmsg = 100;
    attr.mq_msgsize = MSG_SIZE;
    attr.mq_flags = 0;

    mq_unlink(CENTRALBOX);
    mq_central = mq_open(CENTRALBOX, O_RDONLY | O_CREAT, S_IRWXU, &attr);
    while(1)
    {
        //Wait to recieve message from user
        int tempMsgVal = mq_receive(mq_central, buf, MSG_SIZE, 0);
        if(tempMsgVal != -1)
        {
            cout << tempMsgVal;
        }

        if(tempMsgVal != -1){
            QString tempS = buf;
            QStringList tempSL = tempS.split(":");
            if(tempSL.size() == 2 && tempSL.at(0) == "started")
            {
                int x = 0;
                bool exists = false;
                for(int i = 0; i < mq_external.size(); i++)
                {
                    x = QString::compare(tempSL[1], users.at(i), Qt::CaseInsensitive);
                    if(x == 0)
                    {
                        exists = true;
                        break;
                    }
                }

                if(!exists)
                {
                    sprintf(buf,"joined");
                    QString tempS1 = tempSL[1] + "new";
                    QByteArray byteArray = tempS1.toUtf8();
                    const char* tempr = byteArray.constData();
                    mqd_t tempMQ = mq_open(tempr, O_RDWR);
                    int tempI = mq_send(tempMQ, buf, strlen(buf), 0);

                    join(tempSL[1]);
                }
                else
                {
                    sprintf(buf,"invalidname");
                    QString tempS1 = tempSL[1] + "new";
                    QByteArray byteArray = tempS1.toUtf8();
                    const char* tempr = byteArray.constData();
                    mqd_t tempMQ = mq_open(tempr, O_RDWR);
                    int tempI = mq_send(tempMQ, buf, strlen(buf), 0);
                }//Endelse
            }//Endif
        }//Endif

    }//Endwhile
}

void Server::join(QString name)
{
    emit joined(name);
}

这是我在两个类中都包含的messages.h文件:

#ifndef MESSAGES_H
#define MESSAGES_H

#define MSG_SIZE 150
#define CENTRALBOX "/CentralMailBox"

#include <stdio.h>
#include <stdlib.h>

#endif // MESSAGES_H

客户端和服务器类中的一些代码与gui有关,但我已经测试了该部分,并且在正确的时间调用了相关的方法。

我的问题是,当我在第一次调用客户端函数中调用mq_send方法时,它返回并且错误并且对于服务器类是相同的,在发送和接收消息时我是否做错了因为我无法理解我的生活。

2 个答案:

答案 0 :(得分:0)

我发现了我出错的地方,它是联合国显示的,但是mq_ownbox,使用了我从gui获得的名字,我忘了添加'/'到开头,至于mq_central,设置maxmsg为100导致无效争论

答案 1 :(得分:0)

您已经发现无效参数是由于maxmsg计数太大而出现的,我刚刚了解到Linux系统上的maxmsg大小仅为10。因此,非root用户只能创建最大数量的消息队列。 10个插槽。 root用户可以创建更多内容。

另见人mq_overview

   /proc/sys/fs/mqueue/msg_max
         This file can be used to view and change the ceiling value for
         the maximum number of messages in a queue.  This value acts as
         a ceiling on the attr->mq_maxmsg argument given to mq_open(3).
         The default value for msg_max is 10.  The minimum value is 1
         (10 in kernels before 2.6.28).  The upper limit is
         HARD_MSGMAX.  The msg_max limit is ignored for privileged
         processes (CAP_SYS_RESOURCE), but the HARD_MSGMAX ceiling is
         nevertheless imposed.

         The definition of HARD_MSGMAX has changed across kernel
         versions:

         *  Up to Linux 2.6.32: 131072 / sizeof(void *)

         *  Linux 2.6.33 to 3.4: (32768 * sizeof(void *) / 4)

         *  Since Linux 3.5: 65,536