2010-06-16 34 views

Trả lời

56

Sau đây là ví dụ đơn giản về máy chủ nhận tin nhắn từ khách hàng cho đến khi nhận được thông báo "thoát" yêu cầu dừng.

Mã cho máy chủ :

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <mqueue.h> 

#include "common.h" 

int main(int argc, char **argv) 
{ 
    mqd_t mq; 
    struct mq_attr attr; 
    char buffer[MAX_SIZE + 1]; 
    int must_stop = 0; 

    /* initialize the queue attributes */ 
    attr.mq_flags = 0; 
    attr.mq_maxmsg = 10; 
    attr.mq_msgsize = MAX_SIZE; 
    attr.mq_curmsgs = 0; 

    /* create the message queue */ 
    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr); 
    CHECK((mqd_t)-1 != mq); 

    do { 
     ssize_t bytes_read; 

     /* receive the message */ 
     bytes_read = mq_receive(mq, buffer, MAX_SIZE, NULL); 
     CHECK(bytes_read >= 0); 

     buffer[bytes_read] = '\0'; 
     if (! strncmp(buffer, MSG_STOP, strlen(MSG_STOP))) 
     { 
      must_stop = 1; 
     } 
     else 
     { 
      printf("Received: %s\n", buffer); 
     } 
    } while (!must_stop); 

    /* cleanup */ 
    CHECK((mqd_t)-1 != mq_close(mq)); 
    CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME)); 

    return 0; 
} 

Mã cho client:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <mqueue.h> 

#include "common.h" 


int main(int argc, char **argv) 
{ 
    mqd_t mq; 
    char buffer[MAX_SIZE]; 

    /* open the mail queue */ 
    mq = mq_open(QUEUE_NAME, O_WRONLY); 
    CHECK((mqd_t)-1 != mq); 


    printf("Send to server (enter \"exit\" to stop it):\n"); 

    do { 
     printf("> "); 
     fflush(stdout); 

     memset(buffer, 0, MAX_SIZE); 
     fgets(buffer, MAX_SIZE, stdin); 

     /* send the message */ 
     CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0)); 

    } while (strncmp(buffer, MSG_STOP, strlen(MSG_STOP))); 

    /* cleanup */ 
    CHECK((mqd_t)-1 != mq_close(mq)); 

    return 0; 
} 

Các chung tiêu đề:

#ifndef COMMON_H_ 
#define COMMON_H_ 

#define QUEUE_NAME "/test_queue" 
#define MAX_SIZE 1024 
#define MSG_STOP "exit" 

#define CHECK(x) \ 
    do { \ 
     if (!(x)) { \ 
      fprintf(stderr, "%s:%d: ", __func__, __LINE__); \ 
      perror(#x); \ 
      exit(-1); \ 
     } \ 
    } while (0) \ 


#endif /* #ifndef COMMON_H_ */ 

Biên soạn:

gcc -o server server.c -lrt 
gcc -o client client.c -lrt 
+1

Một nhận xét ngắn. Mã của bạn cho khách hàng bị thiếu sau đây bao gồm để làm cho nó biên dịch: '#include #include #include ' – MKroehnert

+0

Ví dụ rất chi tiết! +++ 1 cảm ơn !! – Viet

+2

Ngọt ngào, tôi yêu thích macro CHECK của bạn. – g33kz0r

1
#include <stdio.h> 
#include <fcntl.h> 
#include <mqueue.h> 

int main(int argc, char *argv[]) 
{ 
    mqd_t mq;    // message queue 
    struct mq_attr ma;  // message queue attributes 
    int status = 0; 
    int a = 5; 
    int b = 0; 

    printf("a = %d, b = %d\n", a, b); 

    // Specify message queue attributes. 
    ma.mq_flags = 0;    // blocking read/write 
    ma.mq_maxmsg = 16;    // maximum number of messages allowed in queue 
    ma.mq_msgsize = sizeof(int); // messages are contents of an int 
    ma.mq_curmsgs = 0;    // number of messages currently in queue 

    // Create the message queue with some default settings. 
    mq = mq_open("/test_queue", O_RDWR | O_CREAT, 0700, &ma); 

    // -1 indicates an error. 
    if (mq == -1) 
    { 
     printf("Failed to create queue.\n"); 
     status = 1; 
    } 

    if (status == 0) 
    { 
     status = mq_send(mq, (char *)(&a), sizeof(int), 1); 
    } 

    if (status == 0) 
    { 
     status = mq_receive(mq, (char *)(&b), sizeof(int), NULL); 
    } 

    if ((status == 0) && (mq_close(mq) == -1)) 
    { 
     printf("Error closing message queue.\n"); 
     status = 1; 
    } 

    if ((status == 0) && (mq_unlink("test_queue") == -1)) 
    { 
     printf("Error deleting message queue.\n"); 
     status = 1; 
    } 

    printf("a = %d, b = %d\n", a, b); 

    return status; 
} 
+2

Có điều gì đó rất sai với việc triển khai của bạn. Đó là một ý tưởng khủng khiếp để vượt qua con trỏ thông qua mqueues, kể từ khi một con trỏ chỉ có giá trị trong quá trình riêng của mình, trong khi mqueues được dự định sẽ được sử dụng giữa các quá trình. Nhưng cuối cùng bạn đang đi qua ints. Nó có thể làm việc chỉ vì sizeof (void *)> sizeof (int) trên hầu hết các kiến ​​trúc. – Juliano

+0

@ Juliano: Cảm ơn, tôi đã sử dụng sizeof (void *), nơi nó phải có sizeof (int). Đây chỉ là một ví dụ tổng hợp để hiển thị việc sử dụng mqueue. Nó thể hiện nội dung của một số nguyên di chuyển qua hàng đợi vào một số nguyên khác, cả hai đều được coi là bộ đệm. –

+0

@Armardeep: sizeof (a) và sizeof (b) sẽ tốt hơn sizeof (int). – camh

0

mq_send(mq, (char *)(&a), sizeof(int), 1) bản sizeof(int) byte từ bộ đệm &a trong trường hợp này, nó không mang theo con trỏ của biến a, nhưng mang giá trị của biến a từ một quá trình quá trình khác. Thực hiện là đúng.

0

Mã như sau để bạn tham khảo:

IPC_msgq_rcv.c

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <stdio.h> 
#include <stdlib.h> 
#define MAXSIZE  128 

void die(char *s) 
{ 
    perror(s); 
    exit(1); 
} 

struct msgbuf 
{ 
    long mtype; 
    char mtext[MAXSIZE]; 
}; 


void main() 
{ 
    int msqid; 
    key_t key; 
    struct msgbuf rcvbuffer; 

    key = 1234; 

    if ((msqid = msgget(key, 0666)) < 0) 
     die("msgget()"); 


    //Receive an answer of message type 1. 
    if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0) 
     die("msgrcv"); 

    printf("%s\n", rcvbuffer.mtext); 
    exit(0); 
} 

IPC_msgq_send.c

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define MAXSIZE  128 

void die(char *s) 
{ 
    perror(s); 
    exit(1); 
} 

struct msgbuf 
{ 
    long mtype; 
    char mtext[MAXSIZE]; 
}; 

main() 
{ 
    int msqid; 
    int msgflg = IPC_CREAT | 0666; 
    key_t key; 
    struct msgbuf sbuf; 
    size_t buflen; 

    key = 1234; 

    if ((msqid = msgget(key, msgflg)) < 0) //Get the message queue ID for the given key 
     die("msgget"); 

    //Message Type 
    sbuf.mtype = 1; 

    printf("Enter a message to add to message queue : "); 
    scanf("%[^\n]",sbuf.mtext); 
    getchar(); 

    buflen = strlen(sbuf.mtext) + 1 ; 

    if (msgsnd(msqid, &sbuf, buflen, IPC_NOWAIT) < 0) 
    { 
     printf ("%d, %ld, %s, %d \n", msqid, sbuf.mtype, sbuf.mtext, (int)buflen); 
     die("msgsnd"); 
    } 

    else 
     printf("Message Sent\n"); 

    exit(0); 
} 

Compile mỗi nguồn tập tin, để có được một nhà văn-thực thi và đọc-thực thi. Như sau ::

gcc -o MQsender IPC_msgq_send.c

gcc -o MQreceiver IPC_msgq_rcv.c

Thi mỗi người trong số những chương trình, bạn có thể gửi tin nhắn và đọc tin nhắn từ hàng đợi tin nhắn.Ngoài ra, hãy thử để xem trạng thái hàng đợi tin nhắn, bằng cách chạy lệnh (ở tiểu bang khác nhau của hàng đợi):

TVV -q

Đối với hệ thống Linux, bạn có thể biết tất cả các chi tiết của IPC cơ chế và hàng đợi sẵn vv, bằng cách sử dụng:

TVV -a

Reference Blog

Các vấn đề liên quan