Return of IPC

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 —

#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 —

#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!

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

Thanks for the response Mario.

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

Do you have an example code?

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.

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.

It’s a prerequisite of our project.