Unix IPC套接字:关闭一端而不读取它

时间:2012-04-30 16:26:00

标签: linux sockets unix ipc pipe

我有一个父进程和一个分叉子进程,它们共享一个用socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)创建的Unix域IPC套接字。这两个进程都关闭socket对的一端,并将另一端保存到sock变量中。之后他们这样做:

int sock; // Unix-domain socket

void child_main()
{
  printf("I am child\n");      
  sleep(1);      
  close(sock);
}

void parent_main()
{
  printf("I am parent\n");

  write(sock, "hello", 5);

  char buf[100];
  int ret = read(sock, buf, 100); // this read will return ECONNRESET
  if (ret == -1) { 
    perror("read");
    exit(-1);
  }
}

父进程将一些数据写入套接字,而子进程不会读取它。相反,孩子关闭了套接字。现在我关注的是父进程中的read失败了ECONNRESET(连接由对等重置),而我希望它将返回“0”表示流结束。因为通过调用close来关闭套接字的另一端正常

现在,我理解这种行为(在不读取待处理数据的情况下关闭套接字会生成ECONNRESET),但这在哪里记录了? man read对ECONNRESET一无所知,但它提到:

  

可能会发生其他错误,具体取决于连接到fd的对象

man page for unix domain sockets只说:

  

ECONNRESET:意外关闭了远程套接字。

但是由于Unix域套接字是本地IPC的东西,我想它可能会更加具体地说明发生此错误时的情况。

我的“更深层次的想法”是这样的:如果规范说明例如:只有当没有数据要从套接字中读取时,close才会生成流末尾标记,它如何​​知道其他进程是否只是要编写一些?这不会造成竞争条件吗?内核如何知道连接是否正常关闭?

1 个答案:

答案 0 :(得分:2)

使用有状态套接字(unix domain或tcp),区分“无数据可用”和另一端套接字关闭的最佳方法是首先使用select(),传递readfds(参见man 2 select) )。如果且仅当select指示读取事件时,则尝试在套接字上读取()。如果读取的字节数为0,则表示套接字已关闭(由对等方重置连接)。