我有两个C文件,server.c和client.c。服务器必须创建一个fifo文件并不断读入它,等待输入。客户端获取其PID并将PID写入fifo。 这是我首先启动的服务器文件:
int main(){
int fd;
int fd1;
int bytes_read;
char * buffer = malloc(5);
int nbytes = sizeof(buffer);
if((fd = mkfifo("serverfifo",0666)) == -1) printf("create fifo error");
else printf("create fifo ok");
if ((fd1 = open("serverfifo",O_RDWR)) == -1) printf("open fifo error");
else{
printf("open fifo ok");
while(1){
bytes_read = read(fd,buffer,nbytes);
printf("%d",bytes_read);
}
}
return(0);
}
我的客户档案:
int main(){
int fd;
int pid = 0;
char *fifo;
int bytes;
if ((pid = getpid()) == 0) printf("pid error");
char pid_s[sizeof(pid)];
sprintf(pid_s,"%d",pid);
if ((fd = open ("serverfifo",O_RDWR)) == -1)printf("open fifo error");
else {
printf("open fifo ok");
bytes = write(fd,pid_s, sizeof(pid_s));
printf("bytes = %d",bytes);
}
close(fd);
return(0);
}
我得到的两个主要问题是:当我将pid写入文件时,它返回我写的字节数,所以它看起来没问题但是当我检查fifo文件的属性时它说0字节。第二个问题是读取不起作用。如果我在它显示之前做了一个printf,但是在它没有并且读取没有返回任何东西之后它就会冻结。 我意识到网站上有很多类似的帖子,但我找不到任何有帮助的帖子。 我正在使用Ubuntu和GCC编译器与CodeBlocks。
答案 0 :(得分:3)
这里有很多不妥之处
char pid_s[sizeof(pid)];
sprintf(pid_s,"%d",pid);
sizeof(pid)
返回pid值的大小,而不是其字符串表示形式,即sizeof(int)
,它是4或8,具体取决于您的体系结构。然后,您继续打印它。如果这有效,它只能运气(你在64位机器上)。正确的方法是,如果你选择这样做,就是分配一个适当大的缓冲区,并使用snprintf确保你不会溢出。 PID适合5位数,所以这样的事情会做:
char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);
当然,您可以一起跳过此步骤并发送pid的原始字节
write(fd, (void*)&pid, sizeof(pid))
现在在服务器中你犯了类似的错误:
char * buffer = malloc(5);
int nbytes = sizeof(buffer);
sizeof(buffer)
再次返回4或8,但是你分配了5个字节,正确的方法是这样做,如果你想在堆上分配(使用malloc),是这样的:
char* buffer = malloc(8);
int nbytes = 8;
或者你可以在堆栈上分配:
char buffer[8];
int nbytes = sizeof(buffer);
sizeof有点神奇,因为如果你传入一个数组,它会返回数组的大小(8 * 1)。
当你正在阅读时,你读了5个字节,这可能是不够的(因为你因为早期的bug而写了8个字节),所以它不会完成。你应该读这样的
int pid;
read(fd, (void*)&pid, sizeof(pid));
另外,如果你真的要读写字符串,你可以这样做:
// client
char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);
write(fd, pid_s, sizeof(pid_s));
// server
char pid_s[8];
read(fd, pid_s, sizeof(pid_s));
另请注意,read可能会返回少于写入的内容,您需要再次调用它以继续阅读...
答案 1 :(得分:0)
这段代码中有很多错误...... 首先,sizeof不是这样的。 为什么要序列化pid?
这是错误的:
char pid_s[sizeof(pid)];
123456是一个int,它不适合这个大小为4的数组,只能打印3个字符...
因为你试图序列化pid你不知道要读取的预期大小,除非你采取最坏的情况并为'\ 0'写10 + 1 ......