Linux programming--Application using FIFO client/server (chapter 13th)

Source: Internet
Author: User
Tags sprintf

13.6.2 uses a FIFO client/server application as the last part of the learning FIFO, and now considers how to write a very simple client/server application through a named pipe. A server process is used to accept requests, process them, and then return the resulting data to the party sending the request: the customer.
If you want to allow multiple customers to be able to send data to the server, assume that the processed data can be split into chunks of data, each of which is less than pipe_buf bytes in length.
Because the server can only process one block at a time, it should be logical to use only one FIFO, where the server reads the data and each client writes data to it. As long as the FIFO is opened in blocking mode, the server and customer are automatically blocked as needed.
It is slightly more difficult to return the processed data to the customer, and a second pipeline is scheduled for each customer to accept the returned data. By adding the client's process identifier PID to the original data passed to the server, both parties can use it to generate a unique name for the pipeline that returns the data.
first write the header file Client.h, which defines the data that the client and server programs will use.
/************************************************************************* > File Name:    client.h > Description:  client.h defines the data that is used by both the client and the server program. > Author:       liubingbing > Created time:2015 July 15 Wednesday 22:21 46 seconds > Other:        client.h ************************************************************************/#ifndef _client _h#define _client_h#endif#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < string.h> #include <fcntl.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h > #define SERVER_FIFO_NAME "/tmp/serv_fifo" #define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo" #define Buffer_size 20struct Data_to_pass_st {pid_t Client_pid;char some_data[buffer_size-1];};
Write the server program SERVER.C, which creates and opens a server pipeline that is set to read-only blocking mode. The server then begins to read the data sent by the customer, which uses the DATA_TO_PASS_ST structure
/************************************************************************* > File name:server.c > Description : The SERVER.C program creates and opens a server pipeline that is set to read-only blocking mode. > author:liubingbing > Created time:2015 July 15 Wednesday 22:22 49 seconds > Other:server.c ****************** /#include "client.h" #include <ctype.h>int main () {int SERVER_FIFO_FD, client_fifo_fd;struct data_to_pass_st my_data;int Read_res;char Client_fifo[256];char *tmp_char_ptr ;/* Mkfifo function creates a named pipe (that is, a special type of file Server_fifo_name) */mkfifo (Server_fifo_name, 0777);/* The Open function opens the Server_fifo_name file, set to O_ Rdonly Blocking mode * Returns the file descriptor */server_fifo_fd = open (Server_fifo_name, o_rdonly) If successful, if (server_fifo_fd = =-1) {fprintf ( StdErr, "Server FIFO failure\n"); exit (exit_failure);} Sleep ();d o {/* read function from Server_fifo_) FD points to a file that reads into sizeof (my_data) bytes of data to My_data pointing to memory * If successful, returns the number of bytes actually read into the data */read_res = Read (SERVER_FIFO_FD, &my_data, sizeof (My_data)), if (Read_res > 0) {/* For the data just read from the customer, the SomeAll characters in _data are converted to uppercase */tmp_char_ptr = My_data.some_data;while (*tmp_char_ptr) {*tmp_char_ptr = ToUpper (*tmp_char_ptr); tmp_char_ptr++;} /* sprintf writes formatted data to Client_fifo pointing to memory */sprintf (Client_fifo, Client_fifo_name, my_data.client_pid);/* The Open function opens the file Client_fifo to o_wronly the write-only blocking mode */CLIENT_FIFO_FD = Open (Client_fifo, o_wronly); if (client_fifo_fd! =-1) {/* The Write function writes the memory from My_data to sizeof (my_data) bytes of data into the file pointed to by CLIENT_FIFO_FD * If successful, returns the actual number of bytes written to the data */write (CLIENT_FIFO_FD, & My_data, sizeof (My_data)); close (CLIENT_FIFO_FD);}} while (Read_res > 0), Close (SERVER_FIFO_FD);/* Close the file descriptor of the server pipeline, delete the FIFO file */unlink (server_fifo_name); exit (Exit_ SUCCESS);}
Writing the client program client.c, the first part of the program checks whether the server FIFO file exists, opens it if it exists, and then gets its own process ID, which forms part of the data to be sent to the server. Next, it creates a customer FIFO, ready for the next part of the content
/************************************************************************* > File name:client.c > Description : The CLIENT.C program first checks to see if the server FIFO file exists, opens it if it exists, and then obtains its own process ID, which forms part of the data to be sent to the server. > author:liubingbing > Created time:2015 July 15 Wednesday 22:23 55 seconds > Other:client.c ****************** /#include <stdio.h> #include "client.h" #include < Ctype.h>int Main () {int server_fifo_fd, client_fifo_fd;struct data_to_pass_st my_data;int Times_to_send;char Client _fifo[256];/* Open function opens file Server_fifo_name, set to o_wronly blocking mode * If successful, returns the file descriptor */server_fifo_fd = open (Server_fifo_name, O _WRONLY); if (server_fifo_fd = =-1) {fprintf (stderr, "Sorry, no server\n"); exit (exit_failure);} /* Get process id */my_data.client_pid = Getpid ();/* sprintf function writes the formatted data to Client_fifo pointing to the in-memory */sprintf (CLIENT_FIFO, Client_fifo_ NAME, My_data.client_pid); if (Mkfifo (Client_fifo, 0777) = =-1) {fprintf (stderr, "Sorry, can ' t make%s\n", Client_fifo); ex It (Exit_faiLURE);} for (times_to_send = 0; times_to_send < 5; times_to_send++) {sprintf (my_data.some_data, "Hello from%d", my_data.client _pid);p rintf ("%d sent%s,", My_data.client_pid, My_data.some_data); write (server_fifo_fd, &my_data, sizeof (my_ Data), CLIENT_FIFO_FD = open (Client_fifo, o_rdonly), if (client_fifo_fd! =-1) {if (read (CLIENT_FIFO_FD, &my_data, sizeof (my_data)) > 0) {printf ("reveived:%s\n", my_data.some_data);} Close (CLIENT_FIFO_FD);}} Close (SERVER_FIFO_FD); unlink (Client_fifo); exit (exit_success);

The results are as follows:

Different customer requests are interleaved, but each customer gets the correct processing data that the server returns to it. Note that the order in which the client requests are interleaved is random, and the sequence in which the server receives customer requests varies depending on the machine, even on the same machine, where each run can vary.
Program Parsing
The server creates its FIFO in read-only mode and blocks until the first customer writes the same FIFO to resume connection. At this point, the server process unblocked and the sleep statement was executed, which allowed the data from the customer to queue
In the actual application, sleep should be removed with almost all of it. This is used only to demonstrate the correct method of operation of the program when there are multiple client requests arriving at the same time.
At the same time, after the client has opened the server FIFO, it creates its own unique named pipe to read the data returned by the server. When this is done, the customer sends the data to the server (if the pipe is full or the server is still stuck in hibernation), and then blocks the read call to its own FIFO, Wait for the server to respond.
After receiving the data from the customer, the server processes it and then writes the customer pipeline and returns the processed data, which touches the customer's blocking state. When the customer is blocked by the contact, it can read the data returned by the server from its own pipeline.
The entire process repeats until the last client closes the server pipeline, which causes the server's read call to fail (return 0) because no process has opened the server pipeline in writing.
If this is a true server process, it will also need to continue waiting for the customer's request, you need to modify it in two ways, as follows:
1. Open a file descriptor on its own server pipeline so that the read call will always block instead of returning 0
2. When the read call returns 0 o'clock, close and reopen the server pipeline, causing the server process to block at the open call to wait for the client to arrive, just as it was initially started.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Linux programming--Application using FIFO client/server (chapter 13th)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.