命名管道如何识别客户端
Named pipes how to identify client
假设我有一个服务器可以根据请求创建验证码图像。
客户端通过带有 6 个聊天词和 ID 的命名管道与服务器通信。
服务器创建图像并通过命名管道将其发送给客户端。
客户端有函数 create_captcha_files(const char* word) 与服务器通信并获取结果并保存在 word.png 文件中。
服务器有一个已经实现的函数size_t captcha(const char* word, char * buffer) 将相应的图像写入缓冲区,返回写入的字节数,最大为 16384bytes。
所以客户端是这样的:
#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);
}
您可以使用 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 */
棘手的是 nfds
这里,它是文件描述符 id 的最大值 + 1。
现在,您不想查看哪个 client/file_descriptor 发送了消息?使用 FD_ISSET()
!
if (FD_ISSET (filedes[0], &read_set))
/* Do something */
if (FD_ISSET (STDIN_FILENO, &read_set)){
/* Do something */
注意:每个文件必须使用FD_ISSET()
descriptor/client.
如果您还有其他问题,请随时提问。
假设我有一个服务器可以根据请求创建验证码图像。
客户端通过带有 6 个聊天词和 ID 的命名管道与服务器通信。
服务器创建图像并通过命名管道将其发送给客户端。
客户端有函数 create_captcha_files(const char* word) 与服务器通信并获取结果并保存在 word.png 文件中。
服务器有一个已经实现的函数size_t captcha(const char* word, char * buffer) 将相应的图像写入缓冲区,返回写入的字节数,最大为 16384bytes。
所以客户端是这样的:
#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);
}
您可以使用 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 */
棘手的是 nfds
这里,它是文件描述符 id 的最大值 + 1。
现在,您不想查看哪个 client/file_descriptor 发送了消息?使用 FD_ISSET()
!
if (FD_ISSET (filedes[0], &read_set))
/* Do something */
if (FD_ISSET (STDIN_FILENO, &read_set)){
/* Do something */
注意:每个文件必须使用FD_ISSET()
descriptor/client.
如果您还有其他问题,请随时提问。