简介
迭代服务器:逐一处理客户请求
代码
myhead.h
#ifndef MYHEAD_H_
#define MYHEAD_H_
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<sys/stat.h>
#define MAXLINE 4096
#endif
server.c
#include"myhead.h"
#define FIFO1 "/tmp/fifo.1"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IROTH|S_IRGRP)
void server(int, int);
int main()
{
char buff[MAXLINE] = {0};
ssize_t len = 0;
char fifoName[64] = {0};
int readfd, writefd, fd;
int readfifo, writefifo;
pid_t pid = 0;
if(((mkfifo(FIFO1, FILE_MODE)) <0) && (errno != EEXIST))
{
perror("create fifo1 fail");
}
readfd = open(FIFO1, O_RDONLY, 0);
//如果没有已经对FIFO1打开的写,则进程一直会阻塞在此,知道客户进程对FIFO1打开写
writefd = open(FIFO1, O_WRONLY, 0);
//保证至少有一个打开的FIFO1写,如果没有则readfd可能会返回0以指示读到一个文件结束符,导致不等待直接返回
while(1)
{
printf("here\n");
memset(fifoName, 0, sizeof(fifoName));
memset(buff, 0, sizeof(buff));
len = read(readfd, &pid, sizeof(pid));
printf("len = %u, pid = %u\n", len, pid);
snprintf(fifoName, sizeof(fifoName), "/tmp/fifo.%u", pid);
if(((mkfifo(fifoName, FILE_MODE)) <0) && (errno != EEXIST))
{
printf("pid = %u", pid);
perror("make fifo error");
}
printf("%s mkfifo\n", fifoName);
len = read(readfd, buff, MAXLINE);
printf("len =%d\n", len);
if(buff[len - 1] == '\n')
len--;
printf("buff = %s\n", buff);
fd = open(buff, O_RDONLY);
printf("fd %u\n", fd);
writefifo = open(fifoName, O_WRONLY);
while((len = read(fd, buff, MAXLINE)) > 0)
{
printf("%s", buff);
write(writefifo, buff, len);
}
printf("pid = %u is closed\n", pid);
close(fd);
close(writefifo);
close(readfifo);
unlink(fifoName);
}
exit(0);
}
client.c
#include"myhead.h"
#define FIFO1 "/tmp/fifo.1"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IROTH|S_IRGRP)
int main()
{
pid_t pid = 0;
ssize_t len = 0;
int readfd, writefd;
char filename[64] = {0};
char buff[MAXLINE] = {0};
pid = getpid();
printf("pid = %u\n", pid);
snprintf(filename, sizeof(filename), "/tmp/fifo.%u", pid);
if(((mkfifo(filename, FILE_MODE)) < 0) && (errno == EEXIST))
{
perror("create fifo error");
}
writefd = open(FIFO1, O_WRONLY);
len = write(writefd, &pid, sizeof(pid));
fgets(buff, MAXLINE, stdin);
printf("buff %s\n", buff);
len = strlen(buff);
if(buff[len - 1] == '\n')
{
len--;
}
len = write(writefd, buff, len);
printf("write %s, len %u\n", buff, len);
readfd = open(filename, O_RDONLY, 0);
//注意各个文件描述符打开读写的顺序,避免形成死锁
while((len = read(readfd, buff, MAXLINE)) > 0)
{
puts(buff);
}
printf("pid = %u is closed\n", pid);
close(readfd);
close(writefd);
unlink(filename);
}
先打开服务进程,然后依次重复打开客户进程,客户进程打开的时间不能有重复,否则服务进程逻辑会乱掉。主要功能简介:客户进程向服务进程传递某个文件名,服务进程读取后再传给客户进程。