Message Queue-based c/s communication

Source: Internet
Author: User
Tags erro
Program:



Program ideas:

Write the functions of the client and the server respectively, and create two clients and one server in the Director's office. Considering the actual situation, the server should have a high priority and use the taskspawn function to create server tasks. Then, wait for the client to obtain a response from the server, delete the queue, and end the program. To demonstrate the client request and server response process, this experiment sends a value when sending the client, which is given when the task is created, and the value is added when each request is made, after obtaining the value, the server increases the value and returns it to the corresponding response queue based on the Client ID. The client function sends data based on the size of the Request queue, and then waits for the response queue to receive the returned results. The waiting queue in the server function is not empty. The request is obtained and returned to the corresponding response queue.


Key code:

main.h#ifndef MAIN_H_INCLUDED#define MAIN_H_INCLUDED#include "vxWorks.h"#include "semLib.h"#include "taskLib.h"#include "msgQLib.h"#include "sysLib.h"#include "stdio.h"#define  CLIENT_TASK_PRI          99#define  SERVER_TASK_PRI          98#define  TASK_STACK_SIZE          5000struct msg{    int id;    int value;};LOCAL MSG_Q_ID requestQId;LOCAL MSG_Q_ID response1QId;LOCAL MSG_Q_ID response2QId;LOCAL BOOL notDone;LOCAL int numMsg = 3;LOCAL STATUS clientTask (int cid, int value);LOCAL STATUS serverTask(void);#endif // MAIN_H_INCLUDED

# Include "Main. H "status clienttask (int cid, int value) {int I, j, k; struct MSG request_msg, response_msg; printf (" clienttask started: cid = % d \ n ", CID); for (I = 0; I <nummsg; I ++) {request_msg.id = CID; request_msg.value = value + I;/* semtake (request_semmutex, wait_forever ); */If (msgqsend (requestqid, (char *) & request_msg, sizeof (request_msg), wait_forever, msg_pri_normal) = Error) {perror (" Error in sending the message to request queue \ n "); Return (error);} else {printf (" clienttask: cid = % d, value = % d \ n ", CID, value + I);}/* semgive (request_semmutex); */}/* receive data from responseq */if (1 = CID) {for (j = 0; j <nummsg; j ++) {/* semtake (responsesponsemmutex, wait_forever); */If (msgqreceive (response1qid, (char *) & response_msg, sizeof (response_msg ), wait_forever) = Error) {perror ("erro R in processing ing the response1 message \ n "); Return (error);} else {printf (" clienttask: Get MSG of Value % d from cid = % d \ n ", response_msg.value, response_msg.id);}/* semgive (responseeclipsemmutex); */} else if (2 = CID) {for (k = 0; k <nummsg; k ++) {/* semtake (response, wait_forever); */If (msgqreceive (response2qid, (char *) & response_msg, sizeof (response_msg), wait_forever) = erro R) {perror ("error in processing the response2 message \ n"); Return (error);} else {printf ("clienttask: get MSG of Value % d from cid = % d \ n ", response_msg.value, response_msg.id);}/* semgive (response2_semmutex); */} else {printf (" clienttask: CID error! \ N ") ;}notdone = false; Return (OK) ;}status servertask (void) {int I; struct MSG response_msg; printf (" \ nservertask started \ n "); for (I = 0; I <nummsg * 2; I ++) {/* semtake (request_semmutex, wait_forever); */If (msgqreceive (requestqid, (char *) & response_msg, sizeof (response_msg), wait_forever) = Error) {perror ("error in processing ing the message \ n"); Return (error );} else {printf ("servertask: Get MSG of Value % d from cid = % d \ n", response_msg.value, response_msg.id);}/* semgive (request_semmutex ); * // * after the obtained value is added, the CID is sent to the corresponding response sequence */response_msg.value + = 1; if (response_msg.id = 1) {/* semtake (responsew.semmutex, wait_forever); */If (msgqsend (response1qid, (char *) & response_msg, sizeof (response_msg), wait_forever, msg_pri_normal) = Error) {perror ("error in sending the message to response1 queue \ n"); Return (error);} else {printf ("servertask sending to response Q1: value = % d \ n ", response_msg.value);}/* semgive (response1_semmutex); */} else if (response_msg.id = 2) {/* semtake (response, wait_forever ); */If (msgqsend (response2qid, (char *) & response_msg, sizeof (response_msg), wait_forever, msg_pri_normal) = Error) {perror ("error in sending the message to response2 queue \ n"); Return (error);} else {printf ("servertask sending to response Q2: value = % d \ n ", response_msg.value);}/* semgive (response2_semmutex); */} else {printf (" error in response_msg, the id = % d \ n ", response_msg.id) ;}} return (OK) ;}status main () {notdone = true;/* response = sembcreate (sem_q_fifo, sem_full); responseeclipsemmutex = sembcreate (sem_q_fifo, sem_full ); response2_semmutex = sembcreate (sem_q_fifo, sem_full); */If (requestqid = msgqcreate (nummsg * 2, sizeof (struct MSG), msg_q_fifo) = NULL) {perror ("error in creating requestq"); Return (error);} If (response1qid = msgqcreate (nummsg, sizeof (struct MSG), msg_q_fifo) = NULL) {perror ("error in creating response1q"); Return (error);} If (response2qid = msgqcreate (nummsg, sizeof (struct MSG), msg_q_fifo) = NULL) {perror ("error in creating response2q"); Return (error);} If (taskspawn ("tservertask", server_task_pri, 0, task_stack_size, (funcptr) servertask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = Error) {perror ("servertask: Error in spawning servertask"); Return (error );} if (taskspawn ("tclienttask", client_task_pri, 0, task_stack_size, (funcptr) clienttask, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = Error) {perror ("clienttask: Error in spawning clienttask1"); Return (error);} If (taskspawn ("tclienttask", client_task_pri, 0, task_stack_size, (funcptr) clienttask, 2, 10, 0, 0, 0, 0, 0, 0, 0) = Error) {perror ("clienttask: Error in spawning clienttask2 "); return (error) ;}while (notdone) {taskdelay (sysclkrateget ();} If (msgqdelete (requestqid) = Error | msgqdelete (response1qid) = Error | msgqdelete (response2qid) = Error) {perror ("error in deleting msgqs"); Return (error);} return (OK );}

Experiment results:

It can be seen that the server task is first entered, and then the client task is entered. After the client sends a message to the Request queue, the server immediately obtains the value because the server has a high priority, therefore, the printed message is printed after the server is blocked, and it can be seen that serverl immediately sends a message to the corresponding response queue. At this time, the value is more than the value sent by the client, the program design was followed. Until all requests of Client1 are responded, Client1 gets the value after adding one from its own response queue, and then Client2 does the same.

The following shows the windview demo result:

The first figure shows that T1 is the case where the supervisor creates three tasks and switches to the server. However, the server is blocked because the request queue is empty and switches to Client1, when Client1 has a request, it switches to the server and responds accordingly. This is also true for Client2.

After a while, because the main program has been waiting for the client to receive the response queue message, it can be seen from the end that the request queue and response queue 1 and response queue 2 have been deleted, the program ends.


Problems:

1. The single line comment "//" in C language cannot be used, and compilation fails.

2. When binary semaphore is used at the beginning, only one task in the queue can be sent or accepted, resulting in a deadlock. Before sending, take the request queue and send it. Because the server has a high priority, the semaphore has not been released yet, and the server receives the request queue and cannot obtain the semaphore, cause a deadlock that persists.

3. In the beginning, we did not consider the actual situation. First, we created Client1 and Client2, and set the priority to the same. In fact, we should first start the server to allow client requests, so we should change the order, create a server task first.

4. Select the task state transition when observing with windview. The default context switch cannot be used at the beginning to observe the expected results. After that, you can see the relevant information by hovering over the mouse, which is very convenient.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.