在一台服务器上,我从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来取消成功。
有人会对如何解决这个问题有任何想法吗?
谢谢,期待:)
答案 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
的不同选项。