07 Linux消息队列Demo
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/23_Linux消息队列Demo$ make
gcc -o client comm.c client.c
gcc -o server comm.c server.c
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/23_Linux消息队列Demo$ make run
./server &
./client
msg_id is 294915
waitting for client message.. .
msg_id is 294915
send start.. .
server<= = client[ 20 ] : Client hello world!
server<= = client[ 11 ] : I'm client
server--> client[ 16 ] : server received
server--> client[ 16 ] : server received
server<= = client[ 8 ] : e( exit)
message queue close success
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/23_Linux消息队列Demo$
Makefile:
default:
gcc -o client comm.c client.c
gcc -o server comm.c server.c
run:
./server &
./client
clean:
rm server client
comm.h:
# ifndef _COMM_H_
# define _COMM_H_
# define SERVER_ID 1
# define CLIENT_ID 2
# define MSG_QUEUE_MAXSIZE 128
extern int create_msg_queue ( void ) ;
extern int get_msg_queue ( void ) ;
extern int destroy_msg_queue ( int msg_id) ;
extern int send_msg_queue ( int msg_id, int channel_id, char * msg, int len) ;
extern int recv_msg_queue ( int msg_id, int channel_id, char * recv_buf) ;
# endif
comm.c:
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <stdio.h>
# include <string.h>
# include "comm.h"
# define MSG_QUEUE_PATH "/tmp"
# define MSG_QUEUE_PROJECT_ID 1
typedef struct msgbuf {
long mtype;
char mtext[ MSG_QUEUE_MAXSIZE] ;
} msgbuf_t ;
static int set_msg_queue ( int flags)
{
key_t key = ftok ( MSG_QUEUE_PATH, MSG_QUEUE_PROJECT_ID) ;
if ( key < 0 ) {
perror ( "ftok" ) ;
return - 1 ;
}
int msg_id = msgget ( key, flags) ;
if ( msg_id < 0 ) {
perror ( "msgget" ) ;
printf ( "please call destroy_msg_queue(), or change the key value and try again\n" ) ;
return - 1 ;
}
printf ( "msg_id is %d\n" , msg_id) ;
return msg_id;
}
int create_msg_queue ( void )
{
return set_msg_queue ( IPC_CREAT | IPC_EXCL | 0664 ) ;
}
int get_msg_queue ( void )
{
return set_msg_queue ( IPC_CREAT) ;
}
int destroy_msg_queue ( int msg_id)
{
int ret = msgctl ( msg_id, IPC_RMID, NULL ) ;
if ( ret < 0 ) {
perror ( "msgctl" ) ;
return - 1 ;
}
return 0 ;
}
int send_msg_queue ( int msg_id, int channel_id, char * msg, int len)
{
struct msgbuf mbuf;
if ( ! msg || len > sizeof ( mbuf. mtext) ) {
printf ( "param %p %d error\n" , msg, len) ;
return - 1 ;
}
mbuf. mtype = channel_id;
memcpy ( mbuf. mtext, msg, len) ;
int ret = msgsnd ( msg_id, ( void * ) & mbuf, len, 0 ) ;
if ( ret < 0 ) {
perror ( "msgsnd" ) ;
return - 1 ;
}
return 0 ;
}
int recv_msg_queue ( int msg_id, int channel_id, char * recv_buf)
{
struct msgbuf mbuf;
if ( ! recv_buf) {
printf ( "param %p error\n" , recv_buf) ;
return - 1 ;
}
ssize_t len = msgrcv ( msg_id, ( void * ) & mbuf, sizeof ( mbuf. mtext) , channel_id, 0 ) ;
if ( len < 0 ) {
perror ( "msgrcv" ) ;
return - 1 ;
}
memcpy ( recv_buf, mbuf. mtext, len) ;
return len;
}
server.c:
# include <stdio.h>
# include "comm.h"
# define SERVER_STRING "server received"
static char rbuf[ MSG_QUEUE_MAXSIZE] ;
int main ( )
{
int msgid = create_msg_queue ( ) ;
if ( msgid < 0 )
return - 1 ;
printf ( "waitting for client message...\n" ) ;
int len;
while ( 1 ) {
len = recv_msg_queue ( msgid, CLIENT_ID, rbuf) ;
if ( len > 0 ) {
rbuf[ len + 1 ] = '\0' ;
printf ( "server<==client[%d]: %s\n" , len, rbuf) ;
send_msg_queue ( msgid, SERVER_ID, SERVER_STRING, sizeof ( SERVER_STRING) ) ;
if ( rbuf[ 0 ] == 'e' ) {
goto exit;
}
}
}
exit:
printf ( "message queue close success\n" ) ;
destroy_msg_queue ( msgid) ;
return 0 ;
}
client.c:
# include <stdio.h>
# include "comm.h"
# define CLIENT_STRING1 "Client hello world!"
# define CLIENT_STRING2 "I'm client"
# define CLIENT_STRING3 "e(exit)"
static char rbuf[ MSG_QUEUE_MAXSIZE] ;
int main ( )
{
int msgid = get_msg_queue ( ) ;
if ( msgid < 0 )
return - 1 ;
printf ( "send start...\n" ) ;
send_msg_queue ( msgid, CLIENT_ID, CLIENT_STRING1, sizeof ( CLIENT_STRING1) ) ;
send_msg_queue ( msgid, CLIENT_ID, CLIENT_STRING2, sizeof ( CLIENT_STRING2) ) ;
int len;
for ( int i = 0 ; i < 2 ; i++ ) {
len = recv_msg_queue ( msgid, SERVER_ID, rbuf) ;
if ( len > 0 ) {
rbuf[ len + 1 ] = '\0' ;
printf ( "server-->client[%d]: %s\n" , len, rbuf) ;
}
}
send_msg_queue ( msgid, CLIENT_ID, CLIENT_STRING3, sizeof ( CLIENT_STRING3) ) ;
return 0 ;
}