簡體   English   中英

如何在Linux中的進程之間交換二進制數據

[英]How to exchange binary data between processes in Linux

我需要創建一個可以進行無線網絡掃描的linux應用程序,將結果放入一個結構中並以某種方式將其發送到另一個將使用該數據的主應用程序。 我最初的想法是在主應用程序中創建一個管道,fork並通過execl啟動另一個進程,它可以寫入管道。 像這樣的東西:

pid_t pid = NULL;
int pipefd[2];
FILE* output;
char line[256];

pipe(pipefd);
pid = fork();
if (pid == 0)
{
// Child
  close(pipefd[0]);
  dup2(pipefd[1], STDOUT_FILENO);
  dup2(pipefd[1], STDERR_FILENO);
  execl("/sbin/wifiscan", "/sbin/wifiscan", (char*) NULL);
}

//Only parent gets here. Listen to what the wifi scan says
close(pipefd[1]);
output = fdopen(pipefd[0], "r");

while(fgets(line, sizeof(line), output))
{
//Here we can listen to what wifiscan sends to its standard output
}

但是,如果輸出中出現二進制0,則無法使用二進制數據。 所以我可以將wifiscan應用程序的輸出格式化為文本,將其發送到管道並在主應用程序中解析,或者以我還不知道的更智能的方式進行。

在Linux中的進程之間可靠地交換數據的其他方法是什么?

我懷疑發生了什么是fgets()正在正確地讀取NUL字符,但是你將第一個解釋為讀取的行的結尾。 它很棘手,因為fgets()用於文本輸入,它確實使用'\\ 0'作為標記,而不是返回讀取的字符數。 即使你知道每一行會\\n終止,還有的posibility嵌入在一行原始二進制數據將包括一個\\n了。 所以,切換到fread() ,這是二進制文件。 您可以在每條消息的前面放置一個固定長度(例如2字節,4字節)的消息大小,以便另一方可以先讀取該消息,然后對確切的消息大小執行fread() ,避免出現部分雜亂的問題消息讀取。

如果你真的想保留一些奇怪的文本和二進制混合,你可以嘗試在fgets()之后使用ftell() fgets()來找出你的流進一步的數量,以及你的緩沖區應該有多少個字符,但是我從來沒有見過一個嚴肅的系統做一些如此hacky的事情。

對於記錄而言,如果沒有對二進制數據中的每個字符進行十六進制編碼等非常低效的操作,您只需編碼麻煩的字符即可。 例如,可以使用C字符串文字轉義序列, \\0表示NUL, \\\\表示單個\\ 雖然不太容易進行視覺檢查,但使用say octal \\NNN編程/解碼不可打印的字符可能更容易。 如果有很多不可打印的字符,那么base-64 uuencode方法 - 例如在MIME電子郵件附件中使用 - 是另一種合適但完全不可讀的編碼。

有許多..

我會讀史蒂文斯。

http://www.kohala.com/start/unpv22e/unpv22e.html

通常,人們會使用freadfwrite來跨進程交換二進制結構。 它適用於固定長度的記錄,並且發送空值等沒有問題。

我發現在我的漫長職業生涯中,在大多數應用程序中,交換ascii字符串,易於解析(例如通過scanf )而不是二進制數據要好得多。 這樣就可以觀察和記錄消息,並且可以通過遠程登錄和鍵入(通常粘貼)來測試各個進程。 如果程序員可以只讀取消息流量,它只會使開發更容易。

可靠地交換數據? 這讓我想到了0MQ(ZeroMQ)庫:http: //zeromq.org

看看,作為獎勵,您的流程甚至可以在遠程計算機上進行通話。

歡迎來到雲端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM