General
cancel
Showing results for 
Search instead for 
Did you mean: 

How to send data to and from a client in C

SOLVED
Go to solution
Mary Rice
Frequent Advisor

How to send data to and from a client in C

Hello everyone,

I am having a problem in that I need to connect to a server process and send data back and forth over a pipe. I've tried to use the popen function but that only allows my process to talk in one direction. Does anyone have a simple example of what I need to do? I've tried to use the pipe system call but I don't quite understand what it expects.

Thanks in advance, Mary
8 REPLIES
A. Clay Stephenson
Acclaimed Contributor

Re: How to send data to and from a client in C

Hi Mary:

I assume that since you are trying to use pipe() and popen() that this is all running on the same box. If that is the case then I can send you one of my standard functions that is extremely close. It basically setups up a pair of pipes and then forks. The child is then exec'ed into another process and you are ready to talk. I've had to do things like this to do data conversion between two very different databases (e.g. Informix and Oracle). The child might speak Informix and the parent might speak Oracle. If the processes are not related, you could setup named pipes or use IPCS messages.

If you are needing to send data between boxes then a socket example is in order.

Basically, the pipe() system call expects an array of two integers (fdes[2]). It simply
set up one for reading and the other for writing.

Please let me know which kind of communication you are trying to do and I can probably grab one of my standard functions and throw together an example.

Regards, Clay

If it ain't broke, I can fix that.
Mary Rice
Frequent Advisor

Re: How to send data to and from a client in C

Hi Clay,

Thank you for responding so quickly. The two processes will run on the same server so pipes will work. The processes can also be parent and child. I will need to pass arguments to the child process before it is execed. Is that difficult?

Thank you, Mary
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: How to send data to and from a client in C

Hi again Mary,

I have a stand function 'Start_uproc' which does just what you need. It expect you to send in the user process name, any arguments, and a pointer to a 'uproc_rec' that holds the file descriptors and the child pid. Start_uproc then builds an environment suitable for execvp(), creates the pipes(), and fills in the data in the uproc_rec so that the parent process can talk to the child.

The method for setting is bidirectional pipes is rather tedious but it works like a charm.

You actually make 2 pipe system calls and thus you have 4 file descriptors. You then fork().

On the child: Close read_fdes[0] and write_fdes[1]. You then close(0) - stdin and use the dup system call to duplicate the still open write_fdes[0]. This take advantage of the fact that dup always returns the lowest available fdes. Since we just closed 0 - stdin, we now have a stdin in for the child. Similarly, we close(1) and do a dup(read_fdes[1]) for the child's stdout.

On the parent: Close read_fdes[1] and write_fdes[0]. The remaining file_descriptor read_fdes[0] is used to read from the child and write_fdes[1] is used to write to the child process.

The whole idea behind this is that the parent process (actually the client) writes something to the child (the server) and then reads a response.

To make things very simple in the example, I used fdopen to open high-level files but you could just as easily used the file descriptors and use read() and write() instead. That is up to you. Notice also that I use kill to send a SIGTERM to the child process when we are done.

I've split this into two attachments. This one is the C portion; it calls a very simple child process script but I included in the example some silly arguments for the child process.

I simply call this pipes.c. Compile it like this: cc -Ae pipes.c -o pipes

Regards, Clay
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: How to send data to and from a client in C

Hi again:

Here is a really dumb server script that essentially echoes what is sent to it plus a little bit of fluff. I call it 'stupid.sh'. All you need to do is make it executable via chmod and install it in the same directory that you compile the 'pipes' program.

Basically, when you run pipes, it will send 10 messages to the server; the server will read these one at a time and add a bit of fluff and send it back to the client program. Nevertheless, this should serve as a very solid starting point.

Enjoy, Clay
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: How to send data to and from a client in C

Hi Mary:

I suppose I should add that you should examine all that fork(), close(), exec(), and dup() stuff very carefully. Man 2 fork, exec, and dup and read those man pages very carefully. The whole idea is that we end up with the child process stdin and stdout connected to pipes on the parent process. Warning: The Start_uproc build an environemnt for each process spawned. It makes no attempt to recover the dynamic memory. If you spawn many, many processes then you might want to think about freeing that memory. Normally, you only spawn one or two children so the memory leakage is not a problem.

Food for thought, Clay
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: How to send data to and from a client in C

Hi Mary:

I thought of one other thing that I should add. The first two arguments (progname and args) can be built up with sprintf to produce very complex argument lists. In the example, I simply hard-coded these but you could build them 'on the fly'. Note the convention for including quotes (both " and '), this allows you to build complex args with whitespace and have them parsed correctly.Typically just after Start_uproc is called and before any data is read by the child, the arguments are used to setup the child environment (e.g. set ORACLE_SID). Any initial setup should be done by the child at this time. The parent may have already sent the first request but will block until the child actually does its first read.

Regards and happy coding, Clay

If it ain't broke, I can fix that.
Mary Rice
Frequent Advisor

Re: How to send data to and from a client in C

Thank you, Clay.

Your example compiled and worked the first time. This is just what I needed!!! It took me a little while to understand how this works but now I've got it.

Mary
A. Clay Stephenson
Acclaimed Contributor

Re: How to send data to and from a client in C

My pleasure, Mary.

This is actually a technique from the misty dawn days of UNIX and is really a rather standard idiom.

One technique that you might use, is to send a 'function code' of fixed length to your server followed by a client read. The read then tells your client how much data to read to complete the request. In this model, the client send a function code to the server. The server then responds and says you have another 367 bytes to grab. The idea is that the client actually does two reads per request: one a fixed length and the other a variable length.

Just one way to get the job done, Clay
If it ain't broke, I can fix that.