2013-10-06 54 views
1

我正嘗試使用Internet域套接字爲聊天應用程序創建一個小型服務器。服務器由調度程序和主服務器組成。C - 通過FIFO將在線程中創建的PIPE FD發送到父進程

調度員負責檢測新的連接請求並在新線程中處理它們。該線程通過FIFO將信息發送到主服務器。線程發送的包具有它創建的管道FD,以便主服務器可以與響應進行通信。調度程序由主服務器用叉子初始化,然後使用execve()

問題是我無法將數據寫入服務器的管道。我得到[EBADF錯誤文件描述符]錯誤。

據我所知,我應該將管道FD從父進程傳遞給子進程,但這種解決方案對我來說並不起作用,因爲我不知道我將需要多少管道同一時間。此外,我不想爲每個線程創建一個FIFO,這意味着我需要爲每個活動的線程創建一個新文件,我認爲這不是一個非常優雅的解決方案。

所以總結:

  • 是否有可能使用管道以這種方式?
  • 如果問題出在 使用管道,爲什麼我不能通過FIFO傳遞管道FD,並在另一個進程中使用 ?我讀過可以通過使用UNIX域套接字 傳遞FD來在無關進程與管道之間通信 。這些方法有什麼區別?
  • 你會推薦什麼解決方案?
+2

有一種機制可以通過套接字連接傳遞文件描述符;它不適用於其他通信機制,如FIFO。 –

+0

我已經添加了「unix」標籤,因爲這似乎是關於unix編程的。 – Joni

回答

2

如果您創建從fork主服務器的調度員也不會共享該文件描述符表:調度員將首先得到的文件描述符的副本,但是任何文件或套接字調度員打開之後會只在調度員中打開。

要創建調度程序,您應該使用共享文件描述符表的方法。例如,您可以使用pthreads線程。如果您使用Linux,則可以將fork替換爲低位clone函數,其中包括CLONE_FILES

+0

謝謝你的回答喬尼。我現在明白,問題在於每個進程都有不同的文件描述符表,因此每個進程的相同fd描述符編號引用不同的資源,因此不能以這種方式使用管道,除非修改了底層fd表。我使用的是OSX,因此我認爲clone()不可用。是否有可能從一個線程產生新的線程? – enzo

+0

在OS X上,您可以使用pthreads或Cocoa線程,請參閱https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/AboutThreads/AboutThreads.html – Joni

1

您只能通過'Unix域'(本地域,而不是IPv4或IPv6)套接字在同一臺計算機上的兩個進程之間傳輸打開的文件描述符。傳輸的文件描述符的類型可以是任何有效的文件描述符,但傳輸機制必須是在已經具有文件描述符打開的進程中使用sendmsg()的Unix域套接字文件描述符,並且在正在獲取訪問的進程中使用 recvmsg()到一個描述符(儘管大部分所需的信息都被隱藏在<sys/socket.h>的描述中)。