bash接收udp包tcpdump

时间:2013-05-16 09:49:05

标签: bash udp tcpdump netcat

在一台服务器上,我从192.168.0.21上运行的应用程序接收192.168.0.51上的udp数据包,并且必须使用特定的确认数据包进行回复。

我写的解决方案如下:

#!/bin/bash
send_ack() {
<calculate $ack - code removed>
echo -n "$ack" | nc -u -w1 192.168.0.21 8076
}
while [ 1 ]
do
    for string in $(/usr/sbin/tcpdump -Avnni eth0 -c 1 dst 192.168.0.51 and udp port 8076)
    do
        send_ack &
    done
done

问题是,当数据包到达太快时,我似乎有一些运行条件,我猜它们在tcpdump重启之前到达。 我尝试使用单行缓冲区-l而不是-c 1来取消成功。

有人会对如何解决这个问题有任何想法吗?

谢谢,期待:)

1 个答案:

答案 0 :(得分:1)

程序中的问题是数据包会在tcpdump调用之间滑过,因为您只是运行它来使用-c 1捕获单个数据包,然后每次都退出。

解决方案是在行缓冲模式(-l)中连续运行tcpdump,并将其输出通过管道传输到读取该进程的进程。

#!/bin/bash
# tcpdump line buffered and piped to infinite loop
/usr/sbin/tcpdump -Avnni eth0 -l dst 192.168.0.51 and udp port 8076 | \
  while true; do
    # read output line by line
    read result
    # only act on non-blank output
    if [ "$result" != "" ]; then
      echo "Read a packet: $result"
      # perform whatever action
      send_ack &
    fi
  done

除此之外,您还可以尝试使用-B tcpdump选项来设置缓冲区大小,并使用read的不同选项。