1 Replies - 3993 Views - Last Post: 01 March 2008 - 05:51 PM Rate Topic: -----

#1 eevne  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-February 08

Problem with sending and recieving messages from queue after the first

Post icon  Posted 29 February 2008 - 02:51 PM

Hey everyone, first time poster so go easy on me. Basically what this program is supposed to do is grab the file name from the user in the parent process. It then uses message queues to send the file name to the forked child process. Child process then opens file from msgrcv, appends a string with the file contents and msgsends the file back to the parent process who receives and display the contents of the string (file contents).

I accomplished this fine using pipes but for some reason when I'm using message queues it only works for the initial send and rcv. When I send and then receive at the end it still displays the initial message which was the file name, which leads me to believe it's not taking the message out of the queue. Any help would be appreciated and thanks in advance.

/*
	Joe Wolschon - cs433 - Assignment two, program one (ipc1.cpp)
	Purpose: Write a Client-Server program in C++ usinng the IPS channel - pipes.
		 The program should: 
			 - The client reads path and writes to the pipe.
			 - Server reads path and opens file. Sends either
			   file or error message to pipe.
			-  Client reads the pipe and display whatever is
			   currentl in there.
*/
#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<iostream>
#include<pthread.h>
#include<sys/wait.h>
#include<fstream>
#include<string>
#include<sys/msg.h>
using namespace std;

struct messageobject{char messagestring[1];};
int main(int argc)
{

  int pip[2], childpid; pipe(pip); size_t buffer; char input_file[255]; int msqid;
  
  struct messageobject *buf;
  key_t key=9532;
  msqid=msgget(key, 2359 | IPC_CREAT);
  
  /*get user input file name*/
  cout<<"File:"; fgets(input_file,255,stdin); input_file[strlen(input_file+1)]='\0'; cout<<endl; 
	
  size_t length=sizeof(long)+strlen(input_file); 
  buf=(struct messageobject *)calloc(length,sizeof(string));
  struct messageobject *buf2=buf;
  struct messageobject *buf3;
  memcpy(buf->messagestring,input_file,length);
  
  std::ifstream testFile(input_file);//test file
	
	if(testFile){FILE *gf;
	/*get buffer size*/
	if((gf=fopen(input_file,"r"))!=NULL){fseek(gf,0,SEEK_END);buffer=ftell(gf);fclose(gf);}}

		
	  msgsnd(msqid,buf,length,0);//write user argument 
	
	childpid=fork();
	
	if(childpid==0){//child process (server)
	
	msgrcv(msqid,buf2,length,0,0);
	std::ifstream testFile(buf2->messagestring);//test if file name is valid from pipe
	if(testFile){
	ifstream fin;
	fin.open(input_file);
	cout<<"Sending message: ["<<buf2->messagestring<<"]..."<<endl;
	string sone,stwo,sthree;
	sthree="";
	getline(fin,sone);
	while(fin){getline(fin,stwo);sthree+='\n'+stwo;}//append file to string
	buf3=(struct messageobject *)calloc(buffer,sizeof(string));
	memcpy(buf->messagestring,sthree.c_str(),buffer);
	fin.close();
	msgsnd(msqid,buf,buffer,0);
	cout<<"...complete!"<<endl;}
	if(!testFile){buffer=23;string error="<<Invalid file>>";msgsnd(msqid,error.c_str(),buffer,0);}}



	else{/*display contents of file in parent process*/
	wait(NULL);/*wait for server(child) to end*/	
	msgrcv(msqid,buf,buffer,0,0);//read data in pip
	cout<<buf->messagestring<<endl;}//should display file but stil displays file name instead
	msgctl(msqid,IPC_RMID,NULL);
	
return 0;}//end main()




Is This A Good Question/Topic? 0
  • +

Replies To: Problem with sending and recieving messages from queue after the first

#2 eevne  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-February 08

Re: Problem with sending and recieving messages from queue after the first

Posted 01 March 2008 - 05:51 PM

Fixed it myself. Decided to scrap it all and code it from scratch again. Found out that I wasn't even creating a message queue which was part of the problem. I guess that's what I get for coding late at night. Here's the working code if anyone runs into a similar problem and searches and finds this topic:

/* Joe Wolschon - CS433 - Assignment 2, program 2 (csque.cpp)
   Purpose: Same as program one but with message queues.
	-Client reads pathname from standard input and sends to message queue.
	-Server reads pathname from message queue and tries to open.
	 Reads files and sends to message queue, otherwise sends error
	 message to message queue.
	-Client reads from the message queue and displays either file info 
	 otherwise displays error message.*/

#include<string.h>
#include<sys/msg.h>
#include<string.h>
#include<iostream>
#include<fstream>
#include<sys/wait.h>
#define MAX_MSG_LEN (4096)
using namespace std;
struct msgbf{char mtext[1];};//buf struct

/*interface*/
int main(void){

 /*grab file name from user input*/
 char input_file[255];//holds file name
 cout<<"File:"; fgets(input_file,255,stdin); input_file[strlen(input_file+1)]='\0';

 /* variables for message queue*/
 int msqid;
 key_t key=926;

 if((msqid=msgget(key, 0755|IPC_CREAT))==-1){perror("msgget");exit(1);}//create new message queue
 
 struct msgbf *buf,*buf2; //create buf struct
 buf=(struct msgbf *)calloc(MAX_MSG_LEN,sizeof(char));//alloc memory for buf struct
 buf2=buf;/*not needed, just used to show that it's relaly getting info from the queue at the end*/
 memcpy(buf->mtext,input_file,MAX_MSG_LEN);//copy input_file to buf->mtext
 
 if(msgsnd(msqid,buf,MAX_MSG_LEN,0)==-1){perror("msgsnd error"); exit(1);}//send message(buf) to queue

 /*fork a process*/
  pid_t cpid; cpid=fork();
  if(cpid==-1){perror("fork failed");exit(1);}//failed to fork a process
  
  if(cpid==0){/*child(server) process*/
  
  if((msgrcv(msqid,buf,MAX_MSG_LEN,0,0))==-1){perror("msgrcv");exit(1);}//recieve message from message queue
  cout<<endl<<"Message received in server: "<<buf->mtext;//display message
  ifstream fin;
  std::ifstream testFile(buf->mtext);//test file name sent to here from message queue
  
  if(testFile){/*valid file*/
  fin.open(buf->mtext);//open file
  string stwo,sthree; sthree="";//string variables to hole file data
  while(fin){getline(fin,stwo);sthree+='\n'+stwo;}//append sthree which each line in the file
  memcpy(buf->mtext,sthree.c_str(),MAX_MSG_LEN);//copy sthree into muf->mtext
  
  if(msgsnd(msqid,buf,MAX_MSG_LEN,0)==-1){perror("msgsend");}//send buf to message queue
  }//end valid file 
  
  if(!testFile){/*invalid file*/
  memcpy(buf->mtext,"<<Invalid File>>",MAX_MSG_LEN);//copy error message to buf->mtext
  
  if(msgsnd(msqid,buf,MAX_MSG_LEN,0)==-1){perror("msgsend");}//send buf to message queue
  }//end invalid file
}//end child
else{/*parent(client) process*/
wait(NULL);
if((msgrcv(msqid,buf2,MAX_MSG_LEN,0,0))==-1){perror("msgrcv");exit(1);}//recieve message from queue
cout<<endl<<"Message Received in client: "<<buf2->mtext<<endl;//display message
msgctl(msqid,IPC_RMID,NULL);}//remove message queue
}//end main()


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1