mqd_t, отправка и получение сообщений
Я работаю над программой, в которой у меня есть один процесс, называемый сервером, и несколько процессов, называемых клиентом, которые могут подключаться к серверу и отправлять ему сообщения<однако по какой-то причине мой клиент не подключается к моему серверу:
Это заголовочный файл для клиентского класса:
#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
Часть кода в классе клиента и сервера связана с графическим интерфейсом, но я протестировал эту часть, и соответствующие методы вызываются в нужное время.
Моя проблема заключается в том, что когда я вызываю первый вызов метода mq_send в клиентской функции, он возвращает и ошибка, и то же самое для класса сервера. Есть ли что-то, что я делаю неправильно, когда дело доходит до отправки и получения сообщений, потому что я могу не понять это для жизни меня.
1 ответ
Я узнал, где я ошибался, он не показан, но mq_ownbox использовал имя, которое я получил из графического интерфейса, и я забыл добавить '/' в начало, как и для mq_central, установив maxmsg равным 100 вызвал недействительный аргумент
Как вы уже выяснили, что недопустимый аргумент появился из-за слишком большого количества maxmsg, я только что узнал, что размер maxmsg в моей системе Linux был всего 10. Таким образом, пользователь без полномочий root может создавать очереди сообщений с максимум 10 слотами.. Однако пользователь root может создать и больше.
См. Также man 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