View topic - Return of IPC

Return of IPC

Discussion about the general applications that run on QNX6

Return of IPC

Postby jucaross » Fri Apr 08, 2011 2:40 pm

Hello everybody.

I'm having a problem when I receive the return message from server using IPC and Shared Memory.

I have my server running forever with a while(1) and in a RECEIVE-BLOCKED state.

I send "Testing MessageClient" with the MsgSend command from my client to the server.

The server get the message (MsgReceive), puts it into the Shared Memory, add the text " - Reply from Server" and print it before the reply (until here no problem).

Then returns the content of the Shared Memory with MsgReply and my client shows "Ô}Testing MessageClient". In other words my client don't receive the full and correct message from my server.

Someone knows what's happening?

Below the code:

--- Client ---

Code: Select all
#include <cstdlib>
#include <iostream>
#include <sys/neutrino.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
   char smsg[200] = "Testing MessageClient";
   void * rmsg;
   int coid, rMsgSend;
            
   cout << "Welcome to the Client Message Passing\n" << endl;
      
   /* Establish a connection*/
   coid = ConnectAttach(0, 823315, 1, 0, 0);
   if (coid == -1){
      perror("Error during the ConnectAttach");
      exit(EXIT_FAILURE);
   }
   
   /* Sending the message */
   rMsgSend = MsgSend(coid, smsg, strlen(smsg) + 1, &rmsg, sizeof(&rmsg));
   if (rMsgSend == -1){
      //perror("Error during the MsgSend");
      fprintf(stderr, "Error during the MsgSend: %s\n", strerror(errno));
      exit(EXIT_FAILURE);      
   }   
   
   if (sizeof(rmsg) > 0)
      printf("The server returns the message:\n\t%s\n", &rmsg);
      
   /* Unlink a Connection - It don't make trash's to the Server */
   ConnectDetach(coid);
   
   return EXIT_SUCCESS;
}


--- Server ---

Code: Select all
#include <cstdlib>
#include <iostream>
#include <errno.h> //Needed for the EOK in MsgReply
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/neutrino.h>
#include <string.h> //Needed for strcpy
#include <string>
#include <unistd.h> //Needed for sleep

using namespace std;

int main(int argc, char *argv[]) {

   /* Message Passing */

   int rcvid; //Receive ID
   int chid; //Channel ID
   int fd=0; // File Descriptor
   int rMsgReply; //Return of MsgReply
   int len=262144;
   char message[200];
   char * sharedMemoryName = "/tmp/SharedMemory";
   void * addr; //It needs to be this because mmap returns void *
   
   /* Creating a channel */
   chid = ChannelCreate(0);
   
   /* Server side */
   while (1) {
      rcvid = MsgReceive(chid, message, sizeof(message), NULL);
      if (rcvid == -1)
         MsgError(rcvid, ESRCH);
      printf("Receive ID: %d\n", rcvid);
      printf("Received the message: \n\t\"%s\"\n", message);
      
      /* Creating a Shared Memory Object */
      fd = shm_open(sharedMemoryName, O_RDWR|O_CREAT, 0777);
      
      /* Mapping the Shared Memory Object*/
      addr = mmap(NULL, sizeof(len), PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_PHYS|MAP_ANON, NOFD, 0);
      if (addr == MAP_FAILED)
         perror("Error memory mapping");
      printf("Map address: %p\n", (void *) addr);
      msync(&addr, sizeof(len), MS_SYNC);
      shm_ctl(fd, SHMCTL_GLOBAL | SHMCTL_PHYS | SHMCTL_ANON, NULL, NULL);
      
      /* Writing in the SharedMemory Object */
      addr = strcat(message, " - Reply from Server");
      printf("SHM content: \n\t\"%s\"\n", addr);
      printf("+++ -------------------- +++\n\n");
      
      /* Replying */
      rMsgReply = MsgReply(rcvid, EOK, &addr, sizeof(&addr));
      if (rMsgReply == -1)
         MsgError(rcvid, ESRCH);
         
      /* The memory object remains in the system after the close */
       close(fd);

       /* To remove a memory object you must unlink it like a file.
        * This may be done by another process.*/
      shm_unlink(sharedMemoryName);
   }

   return EXIT_SUCCESS;
}


Thanks in advance!
jucaross
Active Member
 
Posts: 39
Joined: Thu Nov 04, 2010 6:37 pm

Postby mario » Fri Apr 08, 2011 8:56 pm

In the call to mmap you specify a size of sizeof(len), that's only 4 bytes, that's bad.

Not sure what you use msync for.

The strcat doesn't do strcat in shared memory, the destination is message. Your program doesn't write anything to shared memory. The strcat overwrite the variable addr which you need to keep to do the unmmap.

Plus you do a reply of 4 bytes which is the content of the pointer addr, that doesn't really make sense.

I don't understand why you use sharedmem here.

I'm actually very surprise your client printed something that make sense. The server returns a pointer to the string, but to the client that adress is totaly meaning less. Programs have virtual addresses, each program runs with it's own set of adresses that only make sense in the context of the program owning them. My guess is you're just "lucky" and in the client rmsg ends up pointing 2 bytes before smsg, explaining the garbage you get at the front of the string. Just of a test print the adress of smsg and the value of rmsg. I'd bet rmsg is equal to smsg - 2
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Postby jucaross » Mon Apr 11, 2011 2:08 pm

Thanks for the response Mario.

I'm doing this because I need to use IPC with Shared Memory.

Do you have an example code?
jucaross
Active Member
 
Posts: 39
Joined: Thu Nov 04, 2010 6:37 pm

Postby mario » Mon Apr 11, 2011 2:54 pm

The shm_open and mmap need to also be performed in the client. Why do you need to do IPC in shared memory?

There are many way to do what you want to do and posting code although informative can lead you to a less the efficient method given your requirement. Be more precise about what you need to achieve first.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Postby jucaross » Mon Apr 11, 2011 3:13 pm

I have a task at my job that a server share several resources with some client's.
In other words I have two or more processes sharing a memory region.
jucaross
Active Member
 
Posts: 39
Joined: Thu Nov 04, 2010 6:37 pm

Postby jucaross » Mon Apr 11, 2011 5:24 pm

It's a prerequisite of our project.
jucaross
Active Member
 
Posts: 39
Joined: Thu Nov 04, 2010 6:37 pm


Return to QNX6 - Applications

Who is online

Users browsing this forum: No registered users and 1 guest

cron