Files
CS-LABS/kirill/lab_5/server.c
2025-12-11 08:12:48 +07:00

158 lines
4.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// mq_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
#include <mqueue.h> // POSIX message queues
#define MQ_REQUEST "/mq_request"
#define MQ_RESPONSE "/mq_response"
#define MQ_MAXMSG 10
#define BUFFER_SIZE 4096 // msgsize очереди и размер буферов
volatile sig_atomic_t running = 1;
void signal_handler(int sig) {
(void) sig;
running = 0;
}
// Заменить каждый третий символ на пробел
// (позиции 3, 6, 9, ... в исходном тексте)
long long process_text(const char *input, size_t len,
char *output, size_t out_size) {
if (out_size == 0) return -1;
long long replacements = 0;
size_t out_pos = 0;
for (size_t i = 0; i < len && out_pos < out_size - 1; i++) {
char c = input[i];
// считаем позиции с 1
size_t pos = i + 1;
if (pos % 3 == 0) {
output[out_pos++] = ' ';
replacements++;
} else {
output[out_pos++] = c;
}
}
output[out_pos] = '\0';
return replacements;
}
int main(void) {
struct mq_attr attr;
mqd_t mq_req = (mqd_t) -1;
mqd_t mq_resp = (mqd_t) -1;
memset(&attr, 0, sizeof(attr));
attr.mq_flags = 0;
attr.mq_maxmsg = MQ_MAXMSG;
attr.mq_msgsize = BUFFER_SIZE;
attr.mq_curmsgs = 0;
mq_unlink(MQ_REQUEST);
mq_unlink(MQ_RESPONSE);
mq_req = mq_open(MQ_REQUEST, O_CREAT | O_RDONLY, 0666, &attr);
if (mq_req == (mqd_t) -1) {
fprintf(stderr, "ERROR: mq_open(%s) failed: %s\n",
MQ_REQUEST, strerror(errno));
return 1;
}
mq_resp = mq_open(MQ_RESPONSE, O_CREAT | O_WRONLY, 0666, &attr);
if (mq_resp == (mqd_t) -1) {
fprintf(stderr, "ERROR: mq_open(%s) failed: %s\n",
MQ_RESPONSE, strerror(errno));
mq_close(mq_req);
mq_unlink(MQ_REQUEST);
return 1;
}
printf("=== MQ Server started ===\n");
printf("Request queue : %s\n", MQ_REQUEST);
printf("Response queue: %s\n", MQ_RESPONSE);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
char in_buf[BUFFER_SIZE];
char out_buf[BUFFER_SIZE];
while (running) {
unsigned int prio = 0;
ssize_t bytes_read = mq_receive(mq_req, in_buf,
sizeof(in_buf), &prio);
if (bytes_read < 0) {
if (errno == EINTR && !running)
break;
if (errno == EINTR)
continue;
fprintf(stderr, "ERROR: mq_receive failed: %s\n",
strerror(errno));
break;
}
if (bytes_read >= (ssize_t) sizeof(in_buf))
bytes_read = sizeof(in_buf) - 1;
in_buf[bytes_read] = '\0';
printf("Received request: %zd bytes\n", bytes_read);
long long repl = process_text(in_buf, (size_t) bytes_read,
out_buf, sizeof(out_buf));
if (repl < 0) {
const char *err_msg = "ERROR: processing failed\n";
mq_send(mq_resp, err_msg, strlen(err_msg), 0);
continue;
}
printf("Replacements done: %lld\n", repl);
char resp_buf[BUFFER_SIZE];
size_t processed_len = strlen(out_buf);
if (processed_len + 64 >= sizeof(resp_buf)) {
const char *err_msg = "ERROR: response too long\n";
mq_send(mq_resp, err_msg, strlen(err_msg), 0);
continue;
}
memcpy(resp_buf, out_buf, processed_len);
int n = snprintf(resp_buf + processed_len,
sizeof(resp_buf) - processed_len,
"\nREPLACEMENTS:%lld\n", repl);
if (n < 0) {
const char *err_msg = "ERROR: snprintf failed\n";
mq_send(mq_resp, err_msg, strlen(err_msg), 0);
continue;
}
size_t resp_len = processed_len + (size_t) n;
if (mq_send(mq_resp, resp_buf, resp_len, 0) == -1) {
fprintf(stderr, "ERROR: mq_send failed: %s\n",
strerror(errno));
continue;
}
printf("Response sent: %zu bytes\n\n", resp_len);
}
printf("Server shutting down...\n");
mq_close(mq_req);
mq_close(mq_resp);
mq_unlink(MQ_REQUEST);
mq_unlink(MQ_RESPONSE);
return 0;
}