在下面的代码(服务器)中,我需要能够接收客户端的查询,将它们插入 FCFS 队列中,同时,我需要服务器执行这些查询。 我知道下面的代码不能满足我的需要,而且我不知道如何做到这一点。我不能使用信号量、多线程等。如果需要的话,我只允许使用叉子和管道。 我知道我需要在这两个进程之间使用管道,但我不知道如何使用。
服务器.C
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
char** queue = malloc(sizeof (char*) * 15);
int queue_size = 0;
if (mkfifo("fifo", 0666) == -1) {
perror("mkfifo");
return 1;
}
int fd_server = open("fifo", O_RDONLY);
Queue* fcfs_queue = malloc(sizeof(Queue));
newQueue(fcfs_queue);
int pid_enqueue = fork();
if (pid_enqueue == -1) {
return 1;
}
if (pid_enqueue == 0) { //read the input from the client
while(1) {
if (fcfs_queue->head != NULL) {
printf("%s\n", fcfs_queue->head->data);
deQueue(fcfs_queue);
}
}
_exit(0);
} else {
while(1) {
char* toRead = malloc(sizeof(char) * 15);
ssize_t bytes_read = read(fd_server, toRead, sizeof(char) * 15);
if (bytes_read > 0) {
enQueue(fcfs_queue, toRead);
}
}
}
close(fd_server);
return 0;
}
客户端.C
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
//argv[1] must have less that 16 characters
int fd_server = open("fifo", O_WRONLY);
if (fd_server == -1) {
perror("server");
return 1;
}
char* toWrite = strdup(argv[1]);
strcpy(toWrite, argv[1]);
ssize_t bytes_written = write(fd_server, toWrite, strlen(toWrite) + 1);
printf("%d", bytes_written);
close(fd_server);
return 0;
}
QUEUE_MANAGER.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char* data;
struct Node* next;
} Node;
typedef struct {
Node* head;
Node* tail;
int tamanho;
} Queue;
void newQueue(Queue* aux) {
aux->head = NULL;
aux->tail = NULL;
aux->tamanho = 0;
}
void enQueue(Queue* fila, char* toInsert) {
Node* newNode = malloc(sizeof(Node));
if (!newNode) {
perror("malloc");
return;
}
newNode->data = strdup(toInsert);
newNode->next = NULL;
if (fila->tail != NULL) {
fila->tail->next = newNode;
}
fila->tail = newNode;
if (fila->head == NULL) {
fila->head = newNode;
}
fila->tamanho++;
}
void deQueue(Queue* fila) {
if (fila->head != NULL) {
Node* temp = fila->head;
fila->head = fila->head->next;
free(temp->data);
free(temp);
if (fila->head == NULL) {
fila->tail = NULL;
}
fila->tamanho--;
}
}
我已经尝试让服务器请求子进程(如果他可以处理队列), 如果是这样我们就会执行。我在此解决方案中使用了两个管道,但它不起作用。
你们非常接近...
fork
。这会破坏队列,因为服务器的子级写入与服务器父级不同的内存。fdopen
来获取流。服务器需要两个循环:
这是修改后的
server.c
(我已合并到queue.c
):
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char *data;
struct Node *next;
} Node;
typedef struct {
Node *head;
Node *tail;
int tamanho;
} Queue;
void
newQueue(Queue *aux)
{
aux->head = NULL;
aux->tail = NULL;
aux->tamanho = 0;
}
void
enQueue(Queue *fila, char *toInsert)
{
Node *newNode = malloc(sizeof(Node));
if (!newNode) {
perror("malloc");
return;
}
newNode->data = strdup(toInsert);
newNode->next = NULL;
if (fila->tail != NULL) {
fila->tail->next = newNode;
}
fila->tail = newNode;
if (fila->head == NULL)
fila->head = newNode;
fila->tamanho++;
}
void
deQueue(Queue *fila)
{
Node *temp = fila->head;
if (temp != NULL) {
fila->head = temp->next;
free(temp->data);
free(temp);
if (fila->tail == temp)
fila->tail = NULL;
fila->tamanho--;
}
}
int
main(int argc, char *argv[])
{
if (mkfifo("fifo", 0666) == -1) {
perror("mkfifo");
return 1;
}
int fd_server = open("fifo", O_RDONLY);
FILE *fi = fdopen(fd_server,"r");
Queue *fcfs_queue = malloc(sizeof(Queue));
newQueue(fcfs_queue);
char toRead[1000];
while (1) {
char *cp = fgets(toRead,sizeof(toRead),fi);
if (cp == NULL)
break;
// strip newline
toRead[strcspn(toRead,"\n")] = 0;
enQueue(fcfs_queue,toRead);
}
fclose(fi);
while (1) {
Node *cur = fcfs_queue->head;
if (cur == NULL)
break;
printf("%s\n", cur->data);
deQueue(fcfs_queue);
}
return 0;
}
这是修改后的
client.c
:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
// argv[1] must have less that 16 characters
// skip over program name
--argc;
++argv;
int fd_server = open("fifo", O_WRONLY);
if (fd_server == -1) {
perror("server");
return 1;
}
// NOTE: strdup not needed
#if 0
char *toWrite = strdup(argv[1]);
strcpy(toWrite, argv[1]);
#else
char *toWrite;
#endif
#if 1
FILE *fo = fdopen(fd_server,"w");
#endif
#if 0
ssize_t bytes_written = write(fd_server, toWrite, strlen(toWrite) + 1);
printf("%d", bytes_written);
close(fd_server);
#else
for (; argc > 0; --argc, ++argv) {
toWrite = *argv;
fputs(toWrite,fo);
fputc('\n',fo);
}
fclose(fo);
#endif
return 0;
}
在上面的代码中,我使用
cpp
条件来表示旧代码与新代码:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:这可以通过运行文件来清理
unifdef -k
这是客户端命令:
./client quick brown fox jumps over the lazy dog
这是服务器输出:
quick
brown
fox
jumps
over
the
lazy
dog