Re: communication with a daemon
From: Larry I Smith (larryXiXsmith_at_verizon.net)
Date: 08/06/04
- Next message: Jack Klein: "Re: [XPOST] [C] Access speed: pointers Vs array"
- Previous message: Vicky: "UART, readin outgoing buffer size"
- In reply to: Tobias Wagner: "communication with a daemon"
- Next in thread: Larry I Smith: "Re: communication with a daemon - Example Code"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 05 Aug 2004 23:59:08 GMT
Tobias Wagner wrote:
> Hi,
> I want to write a daemon and a client (in C). The client is started several
> times, the daemon only once. The client is structured as follows:
>
> if daemon is not running:
> start daemon
> tell daemon to increase a certain reference counter
> ask daemon for an integer
> do_something
> tell the daemon to decrease the reference counter
> exit
>
> Daemon and client live on the same host. How can I do this in a simple
> manner?
>
Here's a working example.
It's just a skeleton and could be enhanced significantly,
but maybe it'll get you started.
Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.
------------------------------------------
// daemon.cpp
// parent/child socket test program.
// compile with: g++ -o daemon daemon.cpp
#include <errno.h> // perror
#include <sys/types.h> // socket stuff, fork
#include <sys/socket.h> // socket stuff
#include <sys/wait.h> // waitpid
#include <unistd.h> // read, write, fork
#include <iostream> // std::cout, std::endl, etc
#include <string> // std::string::*
// read bytes from file/socket handle 'fd' and put them into
// string 'str'. stop reading when a newline or read error is
// encountered. the trailing newline is NOT put into 'str'.
// (i.e. a newline denotes the end of a discrete message).
// returns true on success, false on read error.
bool
read_line(int fd, std::string & str)
{
char ch;
str.erase(); // erase any existing content in 'str'
// we don't know how much is coming, so we read
// one char at a time. we quit reading on error
// or when a newline is read.
while (1 == read(fd, &ch, 1))
{
if ('\n' == ch)
return true; // success
// append one copy of the byte read to 'str'.
// 'str' will auto-expand (in increments) as
// req'd.
str.append(1, ch);
}
return false; // read error
}
// write string 'str' to file/socket handle 'fd'.
// if 'str' does not end with a newline, one is appended to the
// output (i.e. a newline denotes the end of a discrete message).
// returns true on success, false on write error.
bool
write_line(int fd, const std::string & str)
{
std::string::size_type x;
std::string::size_type len;
len = str.length(); // get the length of 'str'
// write each char individually.
// C++ strings may contain any amount of arbitrary
// binary data. if we used the 'str.c_str()' method
// to create a nul-terminated 'C' string from 'str',
// then we might not get all of 'str' - if it contained
// embedded '\0' bytes.
for (x = 0; x < len; x++)
{
if (1 != write(fd, &str[x], 1))
return false; // return false on error
}
// if 'str' did not end with a newline, append one
// to the output
if (len > 0 && '\n' != str[len - 1])
write(fd, "\n", 1);
return true; // success
}
int
main (int argc, char * argv[])
{
pid_t child;
int sv[2];
// make a pair of connected sockets in sv[].
// the parent process will read/write using sv[0].
// the child process will read/write using sv[1].
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv))
{
perror("socketpair(sv) failed");
return 1;
}
child = fork(); // start the child process
if (child < 0)
{
perror("fork() failed");
return 2;
}
if (0 == child)
{ // I am the child process. I will read/write using sv[1].
close(sv[0]); // close the socket handle not used by me
// create a C++ string 'str' with the specified
// initial content.
std::string str("child says hello");
// send a line to my parent.
// Note that we could have used:
// write_line(sv[1], "child says hello");
// and the compiler would convert the quoted
// string to a C++ std::string for us.
write_line(sv[1], str);
// read a line from my parent into 'str', then print it
read_line(sv[1], str);
std::cout << str << std::endl;
close(sv[1]); // close my socket handle
}
else
{ // I am the parent process. I will read/write using sv[0].
std::string str;
close(sv[1]); // close the socket handle not used by me
// read a line from the child into 'str', then print it
read_line(sv[0], str);
std::cout << str << std::endl;
// reset the content of 'str'
str = "parent says hello";
// send a line to the child.
// Note that we could have used a quoted string
// or a 'char *' variable in place of 'str'
write_line(sv[0], str);
close (sv[0]); // close my socket handle
} // end if
// if we started a child ok, free its resources
if (child > 0)
waitpid(child, NULL, 0);
return 0;
}
- Next message: Jack Klein: "Re: [XPOST] [C] Access speed: pointers Vs array"
- Previous message: Vicky: "UART, readin outgoing buffer size"
- In reply to: Tobias Wagner: "communication with a daemon"
- Next in thread: Larry I Smith: "Re: communication with a daemon - Example Code"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|