Bash

cat 文件到 udp,pt 2:每 ^C 分隔的行發送 1 個 udp 數據包

  • January 31, 2014

昨天我問了一個關於在 bash 中通過 UDP 套接字擷取文件的問題。

我們提出的解決方案是netcat -c -w 1 -v -u -s 127.0.0.1 239.255.0.1 30001 < test.txt. 這在它發送數據包的意義上是有效的,但是有一個問題。

源文件嚴格來說不是文本文件。它實際上是一個二進製文件——內容主要是文本,嵌入了不可列印的字元並且沒有\n行尾。相反,控製字元^C(0x03) 用作行分隔符。

netcat發送數據包時,它會在單個 UDP 幀中發送盡可能多的數據。^C但我希望它在源文件中為每個分隔的消息發送一個 UDP 幀。

例如,如果我的文件包含:

foo^Cbar^Cbaz^C

usingnetcat將導致發送一個 UDP 幀。我想要的是發送 3 條消息:

  1. foo^C
  2. bar^C
  3. baz^C

有沒有辦法做到這一點?


我嘗試了許多可能的解決方案,但沒有任何效果。

對於一個我已經嘗試sedding 源文件來替換^Cwith ^C\n,但這沒有效果:

sed 's/^C/^C\n\0/g' test.txt  | netcat -n -vv -c -w 1 -v -u -s 127.0.0.1 239.255.0.2 30002

我也嘗試將文件轉換為/dev/udp/而不是使用netcat,但結果相似。

cat test.txt > /dev/udp/239.255.0.2/30002

最後我嘗試使用awk一次列印一行並將其重定向到/dev/udp,但結果實際上是一樣的。

似乎兩者netcatcat > /dev/udp緩衝輸入,直到它有一個完整的幀,然後發送幀。那不是我想要的。

我可以刷新 udp 緩衝區,還是以其他方式在源文件中為每個 ^C 分隔的消息發送一條 UDP 消息?

gawk -v 'RS=\03' -v cmd='
 socat -u - udp-datagram:239.255.0.1:30001,bind=127.0.0.1' '
 {print $0 RT| cmd; close(cmd)}' < file

只要兩個 ^C 之間的距離不超過 8k,就應該可以工作。

socat每條記錄執行一個命令(記錄由記錄分隔符變數分隔的^C),記錄加上記錄終止符socat通過管道饋送。

socat一次讀取 8192 個字節,因此它發送的數據包可以達到的大小。

gawk每次寫入(2)作為完整記錄寫入管道。

在此處使用gawk而不是awk確保它正確處理 NUL 字節。

引用自:https://unix.stackexchange.com/questions/111881