2016-06-19 5 views
1

У меня есть сервер, который создает образы captcha по запросу.Именованные каналы, как идентифицировать клиента

Клиенты в сообществе с сервером по именованным каналам с 6 чат-словом и идентификатором.

Сервер создает изображение и отправляет его клиенту по именованным каналам.

Клиент имеет функцию create_captcha_files (const char * word), которая соединяется с сервером и получает результат и сохраняет файл word.png.

Сервер имеет уже реализованную функцию size_t captcha (const char * word, char * buffer), которая записывает в буфер соответствующее изображение, возвращая количество записанных байтов максимум 16384 байт.

Так клиент, как это:

#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; 
} 

и сервер:

#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

Вы можете использовать select() ждать что-то произойдет на нескольких файловых дескрипторов, а затем использовать FD_ISSET(), чтобы выяснить, который отправил сообщение дескриптора файла.

Например:

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 */ 

Вы могли бы использовать FD_SET() для каждого клиента. А потом, использовать select ждать клиентов:

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

Tricky вещь nfds здесь, это максимум дескрипторов файлов иды + 1.

Теперь вы wan't, чтобы проверить, какой клиент/file_descriptor отправлено сообщение? Используйте FD_ISSET()!

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

Примечание: Вы должны использовать FD_ISSET() для каждого дескриптора файла/клиента.

Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать.

+0

Я считаю, что я должен избегать использования select(), потому что он не использовался в моих классах (по крайней мере в этот момент), не проще ли это? не использует идентификацию клиента, должен ли клиент быть на некоторое время (1) с открытым трубой, ожидающим соединения? –

+0

Ну, я думаю, вы могли бы использовать какой-то большой массив, в котором вы добавите дескрипторы файлов для клиентов, а затем за один (1) цикл проверить, есть ли что-то для чтения в каждом дескрипторе файла с помощью системного вызова read(). –