我有一個父進程和派生的子進程,它們共享一個Unix域套接字IPC與socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)
創建。這兩個進程關閉socketpair的一端,並將另一端保存到sock
變量中。之後,他們做到這一點:的Unix IPC插座:關閉一端而不閱讀它
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
只有在沒有數據要從套接字中讀取時纔會生成流結束標記,它如何知道其他進程是不是隻寫一些?這不會造成競爭狀態嗎?內核如何知道連接是否將被正常關閉?
不太確定這是否會有所幫助,但是您是否在'close()'之前嘗試過使用'shutdown()'? – Hasturkun
我剛試過,並使用'shutdown(); close();'表現相同,但使用'shutdown();睡眠(1); close();'實際上正常關閉連接。所以它似乎創造了一個競賽條件,當套接字的另一端「輪到」轉速足夠快時,它會沒事的。所以這是不必要的,我不能稱之爲「睡眠(...)」。 – kuba