此代码使用 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);
}
服务器.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));
}
}
}
如果我尝试使用以下命令编译这些文件:
gcc -o 服务器server.c
gcc -o 客户端 client.c
并运行文件:
./服务器 123 &
./客户
服务器正在运行并等待,
(基本)用户@PC:~/UNIX/mqueues$ ./server 123 &
[2]93463
(基本)user@PC:~/UNIX/mqueues$ 用法:./server msq_id &
/在此等待消息/
然后我尝试从客户端发送消息。但是我从客户端收到错误消息:
(基本)用户@PC:~/UNIX/mqueues$ ./client
cmd>你好
客户端:msgsend:参数无效
我可能做错了什么,如果你能帮助我,我将非常感激。谢谢。
在下面的代码行中,msg_to 未设置为 SERVER。这似乎是个问题。
process_msg(msg.buffer, strlen(msg.buffer));
msg.msg_to = msg.msg_fm;
msg.msg_fm = SERVER;
如果未设置 msg_to,则 msg_type 对于 msgsend() 调用无效,并且可能会失败。