-
September 30th, 2014, 09:52 PM
#1
How can I get my client to wait to open a file until my server has made it?
I have a client/server program. My Client process spawns my server process using a `fork()` and `system()` call. The client and the server are meant to communicate to each other through named piped, that is a requirement of my homework. The client and the server are supposed to initially send a message to the other one, through a pipe, to confirm that a connection is made. My issue is that my client is trying to open one of the named pipes before the server has a chance to make it. This doesn't always happen though. Occasionally, it will run fine. Is there some way to synchronize this?
My overall goal is to get a filename and search target from the user, send those to the server through a named pipe. And the server searches for the target and sends info back.
OUTPUT:
Code:
Client: PID 2986 - Running on Tue Sep 30 20:59:28 2014
Client: PID 2986 - Enter File Name: largeSampleText.txt
Server PID 2988 - Running on Tue Sep 30 20:59:32 2014
Server: PID 2988 - Synchronized to Client.//This means the client-to-server fifo is working
There was an error opening serverToClientfifo//This means client couldn't open the server-to-client fifo
error is: 2//This means the fifo doesn't exist yet
Client: PID 2986 - Enter Target:
s
Client: PID 2986 - Input File >>>largeSampleText.txt<<<
Client: PID 2986 - Target >>>s<<<
Client received unexpected connection message
Message was: D(Ã*ì4
Terminating
CORRECT OUTPUT:
Code:
Client: PID 2542 - Running on Tue Sep 30 20:58:44 2014
Client: PID 2542 - Enter File Name: largeSampleText.txt
Server PID 2557 - Running on Tue Sep 30 20:58:54 2014
Server: PID 2557 - Synchronized to Client.
Client: PID 2542 - Enter Target:
was
Client: PID 2542 - Input File >>>largeSampleText.txt<<<
Client: PID 2542 - Target >>>was<<<
Client: PID 2542 - Synchronized to Server
//The results of the search follows
RELEVANT CLIENT CODE:
Code:
int main()
{
char requestedFileName[1024];
//Get initial information on the client
pid_t clientPID = getpid();
time_t currentTime = time(0);
char* stringTime= ctime(¤tTime);
cout << "Client: PID " << clientPID <<" - Running on "
<< stringTime;
//Get file name from user
cout << "Client: PID " << clientPID <<" - Enter File Name: ";
cin >> requestedFileName;
//Launch the server process
int status = 0;
pid_t childPID;
if(fork() == 0)
{
childPID = getpid();
status = system("pipedServer");
return 0;
}
//Create the client -> server pipe and send connection message
mkfifo ("clientToServerfifo", 0666);
mkfifo("serverToClientfifo",0666);
int fd = open("clientToServerfifo", O_WRONLY);
char connectionMessage[] = "client attempting to connect";
write(fd, connectionMessage, sizeof(connectionMessage));
//Connect to fifo as reader
int fd2, maxBufferSize = 1024;
char buffer[maxBufferSize];
char expectedConnectionMessage[]="server attempting to connect";
fd2 = open("serverToClientfifo", O_RDONLY);
if(fd2 == -1) {cout <<"There was an error opening serverToClientfifo" <<endl;
cout << "error is: " <<errno <<endl;}
// Recieve connection message
read(fd2, buffer, maxBufferSize);
//Get target search term
char requestedTarget[1024];
cout << "Client: PID " << clientPID <<" - Enter Target: " <<endl;
cin >> requestedTarget;
cout << "Client: PID " << clientPID <<" - Input File " << ">>>"
<<requestedFileName<<"<<<"<<endl;
cout <<"Client: PID " << clientPID <<" - Target " << ">>>"
<< requestedTarget << "<<<" << endl;
if(strcmp(buffer,expectedConnectionMessage) == 0)
{
cout <<"Client: PID " << clientPID <<" - Synchronized to Server" << endl;
}
else
{
cout <<"Client received unexpected connection message" << endl;
cout << "Message was: " << buffer << endl;
cout << "Terminating" << endl;
kill(childPID, 0);
return 0;
}
//Send file name and search term to server
write(fd, requestedFileName, sizeof(requestedFileName));
write(fd, requestedTarget, sizeof(requestedTarget));
//Other code follows
RELEVANT SERVER CODE:
Code:
int main()
{
//Get basic server information
pid_t serverPID = getpid();
time_t currentTime = time(0);
char* stringTime = ctime(¤tTime);
cout << "Server PID " << serverPID << " - Running on "
<< stringTime;
//Connect to fifo as reader
int fd, maxBufferSize = 1024;
char buffer[maxBufferSize];
char expectedConnectionMessage[]="client attempting to connect";
fd = open("clientToServerfifo", O_RDONLY);
if(fd == -1) cout <<"There was an error opening clientToServerfifo" <<endl;
//Recieve connection message
read(fd, buffer,maxBufferSize);
if(strcmp(buffer,expectedConnectionMessage) == 0)
{
cout <<"Server: PID " << serverPID << " - Synchronized to Client." <<endl;
}
else
{
cout << "Server received unexpected connection message " << endl;
cout<<"Message: " << buffer <<endl;
cout << "Terminating" <<endl;
return 0;
}
//Create server -> client fifo and send connection message
mkfifo ("serverToClientfifo", 0666);
int fd2 = open("serverToClientfifo", O_WRONLY);
char connectionMessage[] = "server attempting to connect";
write(fd2, connectionMessage, sizeof(connectionMessage));
//other code follows
EDIT: I tried creating both of my fifos in my client and my output changed to this
Code:
Client: PID 3150 - Running on Tue Sep 30 21:23:17 2014
Client: PID 3150 - Enter File Name: largeSampleText.txt
Client: PID 3150 - Enter Target:
Server PID 3153 - Running on Tue Sep 30 21:23:21 2014
was
Client: PID 3150 - Input File >>>largeSampleText.txt<<<
Client: PID 3150 - Target >>>was<<<
Client: PID 3150 - Synchronized to Server
Server received unexpected connection message
Message: was
Terminating
So It appears like the client went ahead and put `requestedFileName` and`requestedTarget`into the pipe and the server read out `requestedTarget` instead of the connection message. Not sure why thoughand the server read out `requestedTarget` instead of the connection message. Not sure why though
-
October 1st, 2014, 03:40 AM
#2
Re: How can I get my client to wait to open a file until my server has made it?
I'm not a unix/linux programmer so there may be a better way of doing it on your system - but an 'easy' way would be that if the open failed to then sleep for say a second and then retry the open. Only if the open retries exceeds a limit (eg 3) is an error reported.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|