this code implements a simple client-server communication system using message queues in C.
local.h
#include <stdio.h>
#include <sys/types.h>
#include "sys/ipc.h"
#include <sys/msg.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#define SEED 'g' /* seed for ftok */
#define SERVER 1L /* message for the server */
typedef struct{
long msg_to; /* placed in the queue for */
long msg_fm; /* placed in the queue by */
char buffer[BUFSIZ];
}MESSAGE;
client.c:
#include "local.h"
int main(int argc, char const *argv[])
{
key_t key;
pid_t cli_pid;
int mid, n;
MESSAGE msg;
static char m_key[10];
cli_pid = getpid();
if((key = ftok(".", SEED)) == -1){
perror("Client: key generation");
exit(1);
}
if((mid = msgget(key, 0)) == -1){
mid = msgget(key, IPC_CREAT | 0660);
printf("%d", mid);
switch (fork()){
case -1:
perror("Client: fork");
exit(3);
case 0:
sprintf(m_key, "%d", mid);
execlp("./server", "server", m_key, NULL);
perror("Client: exec");
exit(4);
}
}
while(1){
msg.msg_to = SERVER;
msg.msg_fm = cli_pid;
write(fileno(stdout), "cmd>", 5);
memset(msg.buffer, 0x0, BUFSIZ);
n = read(fileno(stdin), msg.buffer, BUFSIZ);
if(n == 0){
break;
}
if(msgsnd(mid, &msg, sizeof(msg), 0) == -1){
perror("Client: msgsend");
exit(5);
}
if((n = msgrcv(mid, &msg, sizeof(msg), cli_pid, 0)) != -1){
write(fileno(stdout), msg.buffer, strlen(msg.buffer));
}
}
msgsnd(mid, &msg, 0, 0);
exit(0);
}
server.c:
#include "local.h"
int main(int argc, char const *argv[])
{
int mid, n;
MESSAGE msg;
void process_msg(char *, int);
if (argc != 3) {
fprintf(stderr, "Usage: %s msq_id &\n", argv[0]);
exit(1);
}
while (1) {
if ((n=msgrcv(mid, &msg, sizeof(msg), SERVER, 0)) == -1 ) {
perror("Server: msgrcv");
exit(2);
} else if (n == 0){
break;
} else {
process_msg(msg.buffer, strlen(msg.buffer));
msg.msg_to = msg.msg_fm;
msg.msg_fm = SERVER;
if (msgsnd(mid, &msg, sizeof(msg), 0) == -1 ) {
perror("Server: msgsnd");
exit(3);
}
}
}
msgctl(mid, IPC_RMID, (struct msqid_ds *) 0 );
exit(0);
}
void process_msg(char *b, int len) {
int i;
for (i = 0; i < len; ++i){
if (isalpha(*(b + i))){
*(b + i) = toupper(*(b + i));
}
}
}
If i try to compile these files with using this commands:
gcc -o server server.c
gcc -o client client.c
and run the files:
./server 123 &
./client
Server is running and waiting,
(base) user@PC:~/UNIX/mqueues$ ./server 123 &
[2] 93463
(base) user@PC:~/UNIX/mqueues$ Usage: ./server msq_id &
/waiting for message here/
then i am trying to send a message from client. However i get that error message from client:
(base) user@PC:~/UNIX/mqueues$ ./client
cmd>hello
Client: msgsend: Invalid argument
I'm probably doing something wrong, I'd be very grateful if you could help me. Thanks.
See:
(base) user@PC:~/UNIX/mqueues$ ./server 123 &
[2] 93463
(base) user@PC:~/UNIX/mqueues$ Usage: ./server msq_id &
/waiting for message here/
That means that the server fails (message usage...
).
The first error is that you require to pass 3 arguments to the server, but the last &
is not part of the arguments to the command but used by the shell to launch the command in background.
Second error is that you must create the message queue at first in the server, prior to the call to msgrcv
. If not, how the server would be able to read something?
Third, what logic is behind all of this? The client forks the server, but it seems that you want to run the server by hand too. Forget about running the server from the client.