1

Supose i have a server that creates captcha images on request.

Clients comunicate with the server via named pipes with a 6 chat word and an ID.

Server creates the image and send it to the client via named pipes too.

Client has the function create_captcha_files(const char* word) that comunicates with the server and get the result and saves in a word.png file.

Server has a already implemented function size_t captcha(const char* word, char * buffer) that writes on the buffer the corresponding image, returning the number of written bytes at the maximum of 16384bytes.

So the client is like this:

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>


int main()
{
    int fd, fdin, fdpng;
    char * myfifo = "captcha";
    char id = "001";
    char text[9];
    char buf[1024];
    char png[10];
    char palavra[6];


create_captcha_file(const char* palavra) {
    //write to fifo "captcha" the word + id
    mkfifo(myfifo, 0666);
    strcat(strcat(text,palavra),id);
    fd = open(myfifo, O_WRONLY);
    write(fd,text,9):
    close(fd);
    unlink(myfifo);

    //read anwser from server
    mkfifo(id,0666);
    fdin = open(id,O_RDONLY);
    strcat(strcat(png,palavra),".png");
    //create the .png file
    int fdpng = open(id,O_WRONLY | O_CREAT | O_APPEND,S_IRWXU);
        while((read(fdin,buf,1))) 
            {
             write(fdpng,buf,1);
             }
        close(fdpng);
        close(fdin);
     }
    unlink(id);


    return 0;
}

and the server:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{


    int fd;
    char texto[9];
    char palavra[6];
    char id[3];
    char * myfifo = "captcha";
    buffer[16384];

    //create and read from fifo
    mkfifo(myfifo, 0666);
    fdin = open(myfifo, O_RDONLY);
    read(fdin, texto, 9);
    close(fdin);
    //separate word from id
    for(i=0;i<=9;i++) {
        if(i<7) strcat(palavra,texto[i])
        else strcat(id,texto[i]
    }

size_t captcha(const *char palavra, char * buffer) {
    //create the captcha image and save to buffer
    buffer = create_captcha(palavra);
    return(size_of(buffer));

    }
   captcha(palavra, buffer);

    //write to pipe id the image
    mkfifo(id, 0666);
    fd = open(id, O_WRONLY);
    write(fd,buffer,size_of(buffer)):
    close(fd);
    unlink(fd);

}

1 Answers1

1

You can use select() to wait for something to happen on multiple file descriptors and then use FD_ISSET() to figure out which file descriptor sent message.

For example:

fd_set read_set;
FD_ZERO (&read_set);
FD_SET (filedes[0], &read_set); /* filedes[0] is read end of the pipe */
FD_SET (STDIN_FILENO, &read_set); /* some other file descriptor */

You would use FD_SET() for each client. And then, use select to wait for clients:

if (select (nfds, &read_set, NULL, NULL, NULL) == -1)
                /* Handle error */

Tricky thing is nfds here, it is maximum of file descriptors ids + 1.

Now, you wan't to check which client/file_descriptor sent message? Use FD_ISSET()!

if (FD_ISSET (filedes[0], &read_set))
               /* Do something */
if (FD_ISSET (STDIN_FILENO, &read_set)){
               /* Do something */

Note: You have to use FD_ISSET() for each file descriptor/client.

If you have any further questions, feel free to ask.

Aleksandar Makragić
  • 1,957
  • 17
  • 32
  • i believe i should avoid using select() because it haven't been used in my classes (at this moment at least) isn't it an easier way? not using client identification, should the client be on a while(1) with the pipe open waiting for connection? – José Moreira Jun 20 '16 at 20:33
  • Well I guess you could use some big array where you will add file descriptors for clients and then in one while(1) loop check whether there is something to read on each file descriptor with read() system call. – Aleksandar Makragić Jun 21 '16 at 09:18