【发布时间】:2011-05-21 13:41:33
【问题描述】:
我正在制作一个非常简单的程序,它由客户端使用的一个小 API 和一个服务器进程组成。客户端进程和服务器进程通过一对 FIFO 进行通信(一个与对服务器的请求,一个与来自服务器的响应)。
- 服务器通过阻塞读取(O_RDWR 标志)继续读取请求 FIFO
- 客户端将请求写入请求 FIFO(O_WRONLY 标志)
- 服务器读取请求,对其进行处理并将响应写入响应 FIFO(O_WRONLY 标志)
- 客户端读取响应(O_RDONLY 标志):如果服务器没有传送任何数据(我的意思是未定义的长缓冲区),那么写入 FIFO 的响应就足够了,工作就完成了
- 否则...
- 客户端读取到服务器将要发送数据的响应,因此它再次打开响应 FIFO(O_RDONLY 标志)
- 服务器使用(O_WRONLY 标志)写入数据
在客户端读取另一端之前,最后一次写入似乎不会阻塞服务器进程:为什么?我错过了什么? 为了实现我的目标,我必须在 write 调用之前放置一个 sleep(1) ,但这仅适用于对服务器的某种请求:我该如何帮助您帮助我?
服务器代码
/* until here everything is ok: client read the response and waits for the buffer */
sleep(1);
/* open the FIFO and send the buffer */
if((fifofrom = open(FIFOFROMMMBOXD, O_WRONLY)) == -1) logMmboxd("error in opening FIFOFROM again for the buffer\n", 1);
else logMmboxd("opened FIFOFROM again for the buffer\n", 0);
if((write(fifofrom, mails, sizeof(mmbox_mail_complete)*m)) != sizeof(mmbox_mail_complete)*m) logMmboxd("error in writing FIFOFROM again for the buffer\n", 1);
else logMmboxd("written on FIFOFROM again for the buffer\n", 0);
close(fifofrom);
logMmboxd("messages list definitely sent\n", 0);
客户代码
void lockUp(Request *request, Response *response, void **buffer)
{
int fifofrom, fifoto, lock;
/* lockto access the FIFOs */
if((lock = open(LOCK, O_RDONLY)) == -1) logMmboxman("error in opening LOCK\n", 1);
else logMmboxman("opened LOCK\n", 0);
if(flock(lock, LOCK_EX) == -1) logMmboxman("error in acquiring LOCK\n", 1);
else logMmboxman("acquired LOCK\n", 0);
/* open the FIFO and write the request */
if((fifoto = open(FIFOTOMMBOXD, O_WRONLY)) == -1) logMmboxman("error in opening FIFOTO\n", 1);
else logMmboxman("opened FIFOTO\n", 0);
if((write(fifoto, request, sizeof(Request))) != sizeof(Request)) logMmboxman("error in writing FIFOTO\n", 1);
else logMmboxman("written on FIFOTO\n", 0);
close(fifoto);
/* waiting for response on FIFOFROM */
if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM\n", 1);
else logMmboxman("opened FIFOFROM\n", 0);
if((read(fifofrom, response, sizeof(Response))) != sizeof(Response)) logMmboxman("error in reading FIFOFROM\n", 1);
else logMmboxman("read from FIFOFROM\n", 0);
close(fifofrom);
/* if size>0 then the server has to send a buffer of data to me! */
if(response->size)
{
if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM again for the buffer\n", 1);
else logMmboxman("opened FIFOFROM again for the buffer\n", 0);
*buffer = (void*)malloc(response->size);
if(read(fifofrom, *buffer, response->size) != response->size) logMmboxman("error in reading FIFOFROM again for the buffer\n", 1);
else logMmboxman("read from FIFOFROM again for the buffer\n", 0);
close(fifofrom);
}
/* read the response: I release the lock */
if(flock(lock, LOCK_UN) == -1) logMmboxman("error in releasing LOCK\n", 1);
else logMmboxman("released LOCK\n", 0);
return;
}
【问题讨论】:
-
请张贴代码。根据您的描述无法修复。
-
好的,我正在发布一些代码 :)
-
我怀疑对于这个应用程序,使用 UNIX 域套接字而不是 FIFO 会更好。首先,它们是双向的。