为什么这管道读取阻塞了?

C、C++和Java语言
回复
490365333ibmc
帖子: 413
注册时间: 2011-08-04 4:19
系统: Ubuntu 12.10
送出感谢: 0
接收感谢: 1 次

为什么这管道读取阻塞了?

#1

帖子 490365333ibmc » 2015-10-20 0:01

代码: 全选

//SERVER
#include<fcntl.h>
#include <unistd.h>
#include <stdio.h>

//int clientpipe;

int main(){
	int serverpipe = open("/run/server", O_RDONLY);

	size_t n;
	typedef struct {
		enum {CONNECT, DISCONNECT} cmd;
		pid_t pid;
	} msg_t;
	msg_t msg;
	while(n=read(serverpipe, &msg, sizeof(msg))){
		if(msg.cmd == CONNECT){
			printf("client%d connect\n", msg.pid);
			//clientpipe = open("/run/client", O_WRONLY);
		}
		else{
			printf("client disconnect\n");
			//close(clientpipe);
			break;
		}
	}
	close(serverpipe);

	return 0;
}

代码: 全选

//CLIENT
#include <fcntl.h>
#include <unistd.h>

int main(){
	int serverpipe = open("/run/server", O_WRONLY);
	typedef struct {
		enum {CONNECT, DISCONNECT} cmd;
		pid_t pid;
	} msg_t;
	msg_t msg;

	msg = (msg_t){CONNECT, 0};
	msg.pid = getpid();
	write(serverpipe, &msg, sizeof(msg));

	msg = (msg_t){DISCONNECT, 0};
	write(serverpipe, &msg, sizeof(msg));

	close(serverpipe);
	return 0;
}
用gdb调试发现server里面只有一次读取成功了,打印了client%d connect,但是第二次就阻塞了。为什么?我的client不是写了两次数据进去吗?
附件
test-server.c
(515 Bytes) 下载 64 次
test-client.c
(381 Bytes) 下载 59 次
x724172556
帖子: 4
注册时间: 2016-08-30 17:46
系统: ubuntu16
送出感谢: 0
接收感谢: 0

Re: 为什么这管道读取阻塞了?

#2

帖子 x724172556 » 2016-08-30 17:50

按理说,服务端只运行一次就会退出,因为客户端关掉了写入端;
头像
lilydjwg
论坛版主
帖子: 4165
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

Re: 为什么这管道读取阻塞了?

#3

帖子 lilydjwg » 2016-10-31 18:18

管道是面向流的,不是面向消息(数据报)的。
也就是说,写到管道的消息是没有边界的,多个消息可能会一次读出来,一条消息可能会分布在多次读之中,一次读也可以读到两个「半条」消息。
如果希望保持消息边界,可以使用 SOCK_DGRAM 的 socketpair。
回复

回到 “C/C++/Java”