【发布时间】:2021-06-30 08:35:22
【问题描述】:
我正在用 C 语言编写一个使用 fifos 的客户端-服务器模型。我发送一个文件名和一个唯一 fifo 的名称,供客户端从客户端接收数据,然后服务器打开文件并将其第一行写入 fifo。问题是即使文件存在,我在打开它时也会遇到分段错误。似乎fopen() 函数有效,但我仍然收到错误消息。如果文件不存在,它只会发送一个空字符串。
这里是client.c:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
char name[BUFSIZE];
char recieved[BUFSIZE];
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
sprintf(sc_fifo, "sc_fifo_%d", getpid());
struct sent *sent;
mkfifo(sc_fifo, 0777);
while(1) {
printf("Write the name of the file: ");
scanf("%s", name);
printf("1111\n");
client_server_fifo = open(cs_fifo, O_WRONLY);
printf("2222\n");
printf("%s", name);
printf("%s", cs_fifo);
sent->name = name;
sent->fifo = cs_fifo;
printf("%s", name);
printf("%s", cs_fifo);
write(client_server_fifo, sent, sizeof(*sent));
server_client_fifo = open(sc_fifo, O_RDONLY);
if (read(server_client_fifo, recieved, sizeof(recieved)) == -1) {
printf("An error ocurred.\n");
} else {
printf("First line of the file: \n%s\n", recieved);
close(client_server_fifo);
close(server_client_fifo);
}
memset(recieved, 0, sizeof(recieved));
}
return 0;
}
这里是server.c:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
struct sent *sent;
char name[BUFSIZE];
char line[BUFSIZE];
FILE *file;
printf("Server running...\n");
mkfifo(cs_fifo, 0777);
while (1)
{
client_server_fifo = open(cs_fifo, O_RDONLY);
read(client_server_fifo, sent, sizeof(*sent));
strcpy(name, sent->name);
strcpy(sc_fifo, sent->fifo);
if((file = fopen(name, "r")) != NULL) {
printf("%s\n", name);
fgets(line, BUFSIZE, file);
printf("%s\n", name);
}
server_client_fifo = open(sc_fifo, O_WRONLY);
write(server_client_fifo, line, strlen(line));
memset(name, 0, sizeof(name));
memset(line, 0, sizeof(line));
close(client_server_fifo);
}
return 0;
}
为什么会这样?
【问题讨论】:
-
请为崩溃的程序创建一个minimal reproducible example。然后在调试器中运行它以准确定位崩溃发生的时间和地点,并检查相关变量的值。
-
我正在使用 ssh 在远程服务器中执行此操作。在这里,我有 3 个名为 fitx1、fitx2 和 fitx3 的文件。从客户端发送文件名时,服务器工作正常,直到 fopen 所在的位置,它不会打印其中的内容,然后执行因分段错误而停止。
-
虽然有几点:你为什么使用
malloc来表示单个sent结构?如果您无法打开文件会发生什么(特别是在这种情况下,line的内容是什么)?所有字符串都以空值结尾吗?如果其他地方出现错误会发生什么(总是进行错误检查!)? -
如果您还没有这样做,那么请花点时间阅读the help pages,阅读SO tour,阅读How to Ask,以及作为this question checklist。
-
谁教你像这样把代码塞进一行:
if (read(server_client_fifo, recieved, sizeof(recieved)) == -1)?祝你好运,尝试完全处理read()可以返回的所有事情,当您将调用塞进这样的if语句中时。read()可以返回 any 值,最多包括您请求读取的字节数。它可以在失败时返回-1。它可以在 EOF 上返回0。它可以返回部分结果,这意味着您必须再次调用read()。当调用被塞进if()语句时,您无法处理所有这些。此外,read()不会产生字符串。
标签: c client-server fopen fifo