概括
- read 返回0时,代表对端关闭管道
- 不要使用虚拟机共享目录做以下测试,否则可能会出现:open不阻塞,无法mkfifo,recv在没有数据的情况下一直返回0等问题;
- 只要不设置非阻塞,默认打开的就是阻塞,接收方必须等待发送端打开,否则处于阻塞open
- 发送端只要不close,那么接收端recv就不会返回数据
- 接受方返回数据,一个是有数据,另外一个时对端关闭
测试代码
发送端
using namespace std;
void *UsrReq()
{
int fd = -1, ret;
string temp = "hello";
if (access(REQ_FIFO , F_OK) == -1)
{
if ((mkfifo(REQ_FIFO , 0664) < 0) && (errno != EEXIST))
{
printf("[]mkfifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
}
fd = open(REQ_FIFO , O_WRONLY);
if (fd == -1)
{
printf("[]open fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
// while (true)
{
/* code */
ret = write(fd, (void *)temp.c_str(), temp.length());
cout << "write : " << temp << "ret: " << ret << endl;
sleep(2);
}
getchar();
//(void)close(fd);
return NULL;
}
int main(int argc, char *arg[])
{
UsrReq();
while (true)
{
sleep(1);
}
return 1;
}
接收端
using namespace std;
void *SrvResp()
{
int fd = -1;
int ret;
char temp[8] = {0};
if(access(FIFO , F_OK) == -1)
{
if((mkfifo(FIFO , 0664) < 0) && (errno != EEXIST))
{
printf("[]creat fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
}
fd = open(FIFO , O_RDONLY);
if(fd == -1)
{
printf("[]open fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
while(1)
{
ret = read(fd, &temp, sizeof(temp));
if(ret >= 0)
{
cout<<"Ret:"<<ret <<"Recv: "<< temp <<endl;
sleep(1);
}
else
{
printf("read fifo failed! %s(%d), ret:%d %d %s\n", __FUNCTION__, __LINE__, ret, errno, strerror(errno));
break;
}
(void)usleep(3000);
}
(void)close(fd);
return NULL;
}
int main(int argc, char* arg[])
{
SrvResp();
return 1;
}