簡體   English   中英

如何從 pipe 中讀取長信息?

[英]How to read a long from a pipe?

這涉及進程間通信中的未命名管道。 我有一個 pipe,一個進程在其中存儲一個值,另一個進程想要讀取這個數值,整數或長整數。

這里很好地描述了http://tldp.org/LDP/lpg/node11.html如何在 C 中創建管道。 我的問題是如何從 pipe 中讀取 long 或 int。

從上述頁面中提取:

/* Read in a string from the pipe */
int nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);

好吧,總的來說,我不知道如何在 C 中處理 pipe (它就像一個文件?)以及我如何從它讀取字符串以外的數據。

您不能“真正”從 pipe 中讀取long信息。 您從 pipe 中讀取了一個字節序列,如果您可以定義一些協議,這些字節代表的長度,那么您已經讀取了一個 long。

假設 pipe 的兩端對long使用相同的存儲表示,如果它們是用相同的編譯器為相同的架構編譯的,或者就此而言使用不同的編譯器但使用相同的 ABI,那么你可以write(fd, &src_long, sizeof(long)); 在一端, read(fd, &dst_long, sizeof(long)); 在另一端。 加上或減去通常的混亂,以確保 I/O 沒有提前完成。

pipe 就像一個文件,除了它是不可搜索的。 當您讀取數據時,它從 pipe 中“消失”,無法再次讀取。

您將像從任何其他文件中讀取數據結構一樣。 可以使用 scanf、fstream>> 或使用 read() 和 union 來完成。

由於您的 pipe 的兩端在同一台機器上,因此您不必擔心機器架構的差異; 如果您將問題更改為討論 sockets,您將不得不擔心這一點。

您可以使用以下命令將 long 寫入 pipe:

long l = 0x01020304L
if (write(pipe_w_fd, &l, sizeof(l)) != sizeof(l))
    ...handle error...

您可以使用以下命令從 pipe 中讀取值:

long l;
if (read(pipe_r_fd, &l, sizeof(l)) != sizeof(l))
    ...handle error...

如果您必須處理不同的機器架構,您可以將值格式化為與平台無關的格式(例如大端格式)並在一端寫入,在另一端讀取與平台無關的數據並轉換回本地機器特定的格式。

取決於它是如何發送的。 如果您有一些協議/框架約定,則必須閱讀框架然后提取 int。 如果您只發送 int 本身,則可以讀取 sizeof(int) 字節,然后直接使用緩沖區中的字節:

int foo = *((int*) readbuffer);

由於 pipe 是本地的,因此您不必(在大多數情況下)在這里關心字節順序和大小。

好吧,總的來說,我不知道如何在 C 中處理 pipe (它就像一個文件?)

是的。

以及我如何從中讀取字符串以外的數據。

這是天真的情況,它假設 long 是二進制的並且在系統中大小相同。 如果 long 被寫成一個字符串,讀取一個字符串然后找到 long。

long mylong;
int nbytes = read(fd[0], &mylong, sizeof(long));

它被視為文件。 我會閱讀 scanf 以查看您可以輕松解析哪些數據。 整數、十六進制或八進制整數之類的東西可以很容易地解析,甚至指針也可以解析。 Longs 並不簡單,但您可以從字符串 (%s) 中解析 long 並將其存儲在 long 之后。

http://beej.us/guide/bgc/output/html/multipage/scanf.html

你可以這樣做:

long l;

if (read(fd[0], &l, sizeof(l)) != sizeof(l))
{
   /* TODO: handle this */
}

通過使您的序列化類型變long ,您在這里失去了一些靈活性,因為讀取此數據的人可能會以不同的字節順序或不同的大小結束long 想象一下,作為一個例子,你forkdup2(fd[1], 1)最終在子進程中exec命令......現在數據可能來自另一台機器,並且會有問題. 為避免它,您可以執行以下操作:

/* Type of l has a predictable size. */
uint32_t l;

if (read(fd[0], &l, sizeof(l)) != sizeof(l))
{
   /* TODO: handle this */
}

/* Convert byte order of what we just read */
l = ntohl(l);

實際上,以 32 位增量read有點奇怪……您應該考慮的是提出一種消息格式並一次讀取更大的數據塊。 實現此目的的一個好方法是為每個信息量設置一個 header 來指示后續內容的大小、消息類型等。或者,如果您不覺得這很吸引人,您可以考慮將您的序列化為文本。 這也將為字節順序問題提供一個不錯的答案。

暫無
暫無

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

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