#c #posix #message-queue
#c #posix #очередь сообщений
Вопрос:
У меня есть серверно-клиентская программа, клиент отправляет серверу сообщение, используя a struct
, которое имеет три основных значения: дату и две временные метки.
Теперь, когда сервер получает сообщение, я пытаюсь извлечь дату из структуры сообщения в качестве подстроки массива символов, а затем преобразовать ее в int, но я застрял на несколько часов, даже пытаясь получить соответствующие символы из сообщения.
Моя серверная программа:
#include "msg.h"
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
void delete_mq(char* mname, mqd_t qid) {
if (mq_close(qid) < 0) {
perror("Error closing queue");
exit(1);
}
if (mq_unlink(mname) < 0) {
perror("Error unlinking queue");
exit(1);
}
}
void make_command(MESSAGE *mess, char *mname, mqd_t qid) {
printf("making command, hehen");
if (strcmp(mess->date,"STOP") == 0){
printf("Stopping the server.n");
delete_mq(mname, qid);
exit(0);
}
// this is where I am stuck
char thedate[3];
char *date = mess->date;
strncpy(thedate, date 1, 1);
thedate[2] = '';
printf("%sn", thedate);
strcpy(mess->messtext,"Some text respone message");
}
int main(int argc, char** argv)
{
int flagsc = O_RDONLY | O_CREAT;
mode_t mode = 0600;
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = sizeof(MESSAGE);
attr.mq_curmsgs = 0;
int flags = O_WRONLY;
char cname[10];
char sqname[15];
sprintf(sqname,"%s%s",qname,getlogin());
mqd_t qid = mq_open(sqname, flagsc, mode, amp;attr);
if (qid <0) {
perror("Error opening message queue");
exit(1);
}
for (;;) {
MESSAGE message;
unsigned int priority = 0;
if (mq_receive(qid, (char*) amp;message, sizeof(message), amp;priority) != -1) {
make_command(amp;message, qname, qid);
sprintf(cname,"/%d", message.pid);
message.pid = getpid();
mqd_t cmqid = mq_open(cname, flags);
mq_send(cmqid, (char*)amp;message, sizeof(MESSAGE), 0);
mq_close(cmqid);
}
}
mq_close(qid);
return 0;
}
Моя клиентская программа:
// ./client 11.23. 13:24 16:43
#include "msg.h"
int main(int argc, char** argv)
{
if (argc != 4){
printf("Usage: ./client <date e.g. 11.23.> <time1 e.g. 13:24> <time2 e.g. 16:43>n");
exit(1);
}
int flags = O_WRONLY;
int cflags = O_RDONLY|O_CREAT;
mode_t mode = 0600;
char sqname[15];
sprintf(sqname,"%s%s", qname, getlogin());
mqd_t qid = mq_open(sqname, flags);
if (qid == -1) {
perror("Error opening queue in client");
exit(1);
}
struct mq_attr temp;
if (mq_getattr(qid, amp;temp) == -1) {
perror("Error with getattr in client");
} else {
// finish later
}
char cqname[20];
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 8;
attr.mq_msgsize = sizeof(MESSAGE);
attr.mq_curmsgs = 0;
sprintf(cqname,"/%d", getpid());
mqd_t cqid = mq_open(cqname, cflags, mode, amp;attr);
if (cqid == -1) {
perror("Error opening queue in client");
exit(1);
}
MESSAGE mess;
strcat(mess.date, argv[1]);
strcat(mess.time1, argv[2]);
strcat(mess.time2, argv[3]);
mess.pid = getpid();
printf("Client has sent request");
if (mq_send(qid, (char*) amp;mess, sizeof(MESSAGE), 0) < 0) {
perror("Error sending message in client");
exit(1);
}
if (strcmp(mess.date,"STOP") != 0) {
if (mq_receive(cqid,(char*) amp;mess, sizeof(MESSAGE), 0) < 0) {
perror("Error receiving message in client");
exit(1);
}
} else {
printf("Stopping the client.n");
if(mq_close(qid) < 0) {
perror("error closing server queue");
exit(1);
}
if(mq_close(cqid) < 0) {
perror("error closing client queue");
exit(1);
}
if (mq_unlink(cqname) < 0) {
perror("Error unlinking client queue");
exit(1);
}
exit(0);
}
printf("%sn", mess.messtext);
if(mq_close(qid) < 0) {
perror("error closing server queue");
exit(1);
}
if(mq_close(cqid) < 0) {
perror("error closing client queue");
exit(1);
}
if (mq_unlink(cqname) < 0) {
perror("Error unlinking client queue");
exit(1);
}
exit(0);
}
И заголовок:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <mqueue.h>
#define KEY 1111
typedef struct{
int pid;
// e.g. 11.23.
char date[50];
char time1[50];
char time2[50];
char messtext[10];
} MESSAGE;
char * qname="/server_";
Теперь аргументами для выполнения клиента должны быть дата и две временные метки. Когда сервер получает сообщение, я хочу извлечь первые два символа из date
(месяца) и преобразовать его в int
, чтобы я мог получить соответствующий месяц *months[]
.
Я перепробовал почти все: strcpy
, memcpy
, sprintf
и я схожу с ума, потому что он либо напечатает только первое число месяца, либо неправильно преобразует, либо печатает дополнительные сумасшедшие символы из памяти, и я едва начал разбивать сообщение на части. По mess->date
-видимому, в его первой позиции есть какой-то другой символ, и я не могу его пропустить.
Может ли кто-нибудь помочь мне достичь того, что я описал?
Комментарии:
1.
atoi
cplusplus.com/reference/cstdlib/atoi2. Я пробовал
atoi
, я знаю, для чего это нужно, но я даже не могу дойти до того момента, когда мне придется его использовать. Я не могу извлечь месяц из массива символов.3.
strncpy(thedate, date 1, 1)
означает скопировать 1 символ из строки, начинающейся сdate 1
tothedate
. Итак, еслиdate
это строка «Jan 20», вы бы прочиталиa
в «Jan» только потомуdate 1
, что это строка «an 20», и вы копируете только 1 символ. Я подозреваю, что вам может понадобитьсяstrncpy(thedate, date, 3)
, если вы читаете названия месяцев, такие как «Январь», «Февраль» и т.д. Также имейте в виду, чтоthedate
это не будет завершаться нулевым значением из-за вашего объявленияchar thedate[3];
, которое ограничивает вас такими функциями, какstrncpy/memcpy
иstrncmp/memcmp
которые требуют параметра, указывающего максимальное количество символов для проверки.4. Нет,
date
это строка «11.23.», Но когда я ее печатаю, в первой позиции появляется дополнительный символ, поэтому я попыталсяstrncpy(thedate, date 1, 2)
, но это тоже не работает, по какой-то причине он не копируется11
thedate
. Также обратите внимание, что я завершилthedate
с''
помощью .5.
MESSAGE mess;
в вашем клиентском коде объявляетсяmess
без инициализатора, поэтомуstrcat(mess.date, argv[1]);
можно добавить строку «11.23.» к неинициализированным / мусорным данным. Вы можете исправить эту ошибку, используяMESSAGE mess = { -1 };
для инициализацииpid
поля недопустимый PID. Остальные данные в структуре будут инициализированы нулями иstrcat
будут работать так, как ожидалось. Возможно, это не полное решение, но это начало.