2011-09-12 45 views
1

我正在创建一个相当大的项目,作为一个家庭作业,我需要创建一个服务器程序,它监听2个fifo,客户端将写入。当我在客户端和服务器之间进行一些写入/读取操作时,当我关闭客户端上的fifos时,它看起来像服务器“想象”一样,仍然有人保持这些fifos开放。在FIFO上打开系统调用不阻塞?

因此,服务器尝试在每次操作后读取64个字节,明显失败(读取0个字节)。每个操作这种事情发生只有一次,它不会试图读取64字节

它不创造任何客户端的问题,但它真的很奇怪,我讨厌那些类型的错误

我的认为这是与打开/关闭以及客户使用锁有关的问题。

注,在开放手术中使用的标志在这个伪文本中指定

Server行为:

Open Fifo(1) for READING (O_RDONLY) 
Open Fifo(2) for WRITING (O_WRONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 

客户行为:

Set a lock on Fifo(1) (waiting if there is already one) 
Set a lock on Fifo(2) (same as before) 
Open Fifo(1) for WRITING (O_WRONLY) 
Open Fifo(2) for READING (O_RDONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 
Get lock from Fifo(1) 
Get lock from Fifo(2) 

我不能直接发布代码,除了用于网络的功能,因为项目非常大,我不直接使用系统调用。您在这里:

int Network_Open(const char* path,int oflag) 
{ 
    return open(path,oflag); 
} 

ssize_t Network_IO(int fifo,NetworkOpCodes opcode,void* data,size_t dataSize) 
{ 
    ssize_t retsize = 0; 
    errno = 0; 

    if (dataSize == 0) return 0; 

    while ((retsize = (opcode == NetworkOpCode_Write? write(fifo,data,dataSize) : read(fifo,data,dataSize))) < 0) 
    { 
     if (errno != EINTR) break; 
    } 

    return retsize; 
} 

Boolean Network_Send(int fifo,const void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Write,(void*)data,dataSize); 
} 

Boolean Network_Receive(int fifo,void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Read,data,dataSize); 
} 

Boolean Network_Close(int fifo) 
{ 
    if (fifo >= 0) 
     return close(fifo) == 0; 
} 

任何帮助将不胜感激,谢谢。

EDIT 1:

客户端输出:http://pastie.org/2523854 服务器输出(strace的):http://pastie.org/2523858

+0

您在Network_Open中打开了哪些标记? – asm

+0

O_RDONLY阅读和O_WRONLY写作,没有别的 –

回答

2

来自read()的零字节表示其他进程已完成。现在您的服务器必须关闭原始文件描述符并重新打开FIFO以服务下一个客户端。一旦开始使用新的文件描述符,阻塞操作就会恢复。

这就是它应该工作的方式。 AFAIK,在获得零字节后,进一步尝试读取文件描述符也将永久返回0字节(或直到您关闭文件描述符为止)。即使另一个进程打开FIFO,原始文件描述符也将继续指示EOF(其他客户端进程将挂起,等待服务器进程打开FIFO进行读取)。

3

零字节从(粘连)读()返回指示文件的结束时,即,另一端关闭了FIFO。阅读手册页以供阅读。

+0

我可以理解这一点,但为什么我的服务器打开第一个FIFO(阅读),如果在书写模式另一端没有人? –

+0

是啊,但我打开阻塞模式下的描述符,这就是为什么我不明白这种行为 –

+1

好吧,没有任何代码显示这种行为。如果你只是打开FIFO,读取一些数据,并最终读取返回0,一切都是完全正常的。当读取返回0时,你会做什么?你是否告诉我们你再次打开fifo?客户再次打开它之前?在你的应用程序上运行'strace'来看看会发生什么 – nos