如何使用netcat发送一个UDP数据包?

159

我想在一个UDP数据包中只发送一个短整型值,但运行命令

echo -n "hello" | nc -4u localhost 8000

我可以看到服务器接收了hello,但我必须按下Ctrl+c才能退出netcat命令。

我如何在发送hello后使其自动退出?


抱歉,打扰了。我重新阅读了man页并找到了-q选项。

 echo -n "hello" | nc -4u -q1 localhost 8000

这个程序可以正常工作(它会在1秒后退出)。

但是,使用-q0选项时它不起作用。


Debian 上的 Man 页面:-q seconds:在标准输入结束后,等待指定的秒数然后退出。如果秒数为负数,则永久等待。 - luckydonald
6个回答

249

如果您正在使用bash,那么您可以写

echo -n "hello" >/dev/udp/localhost/8000

避免使用netcat的所有特殊性和不兼容性。

这也适用于发送到其他主机,例如:

echo -n "hello" >/dev/udp/remotehost/8000

这些在文件系统上不是“真实”的设备,而是bash的“特殊”别名。有更多的信息可以在Bash手册中找到。


34
好的,你说得对,让我明确一下,这在ZSH中不起作用。 - jturolla
1
这比使用netcat要好得多。感谢您的提示! - johnboiles
5
这可能是我见过最惊奇的事情。 - freb
7
由于某些原因,我需要在Ubuntu 14.04上使用127.0.0.1而不是localhost。(是的,在/etc/hosts中我确实有localhost。) - tuomassalo
5
/dev/udp/不是真实的文件,它只是由bash特殊解释的文件名。 - Peter Eisentraut
显示剩余11条评论

51

我在netcat上没有找到-q1选项。相反,我使用了-w1选项。以下是我编写的用于发送udp数据包到任何主机和端口的bash脚本:

#!/bin/bash

def_host=localhost
def_port=43211

HOST=${2:-$def_host}
PORT=${3:-$def_port}

echo -n "$1" | nc -4u -w1 $HOST $PORT

1
OS X 的工作方式是这样的:"echo -n "test" | nc -4u -w0 localhost 9999",正如SimonW所说。 - Simon Unsworth

16

在当前版本的netcat (v0.7.1)中,你可以使用-c选项:

-c, --close                close connection on EOF from stdin
因此,
echo "hi" | nc -cu localhost 8000
应该就这样做。

5
需要注意的是,这只适用于GNU netcat,而不适用于BSD netcat。 - MarSoft
1
为了清晰起见,基于Linux的netcat中,-c选项需要一个命令作为参数,该命令通过/bin/bash执行给定的参数。- https://www.commandlinux.com/man-page/man1/nc.1.html - Blake Neal

11

我遇到了同样的问题,但我使用-w 0选项只发送一个数据包并退出。 你应该使用这个命令:

我也有同樣的問題,但我使用 -w 0 選項只傳輸一個封包就退出。 你應該使用這個指令:

echo -n "hello" | nc -4u -w0 localhost 8000

1
nc 1.10-41+b1 不接受 -w0。错误:无效的等待时间0。 - palik
@palik 看起来像是一个 nc.traditional 版本的字符串。-q0 对你应该可行。 - Kenny

6

Netcat每个换行符发送一个数据包,所以您可以放心使用。如果您需要进行更复杂的操作,则可能需要其他工具。

我在使用Wireshark时意识到了这一点,不知道是否有所帮助。


3
我认为这只适用于TCP。对于UDP来说,它会在一个数据包中发送多行文本(如果它们适合的话)。 - sleske
2
只需测试 echo -n "hello\nworld" >/dev/udp/localhost/514,您将获得2行输出。 - bebbo
1
@bebbo,2行,一个数据包 - sehe
@bebbo是正确的。即使对于UDP,这个答案也是不正确的,因为它只适用于TCP。 - Evan

3

不幸的是,nc不是一个独特的工具名称。要找出您使用的nc版本,请查看nc -h的输出的第一行。要发送单个UDP数据包并立即退出,请使用适用于特定nc版本的相应参数。

  • GNU版本: nc -uc localhost 8000 <<<hello
  • BSD版本: nc -uq0 localhost 8000 <<<hello
  • 传统版本: nc -uq0 localhost 8000 <<<hello
  • BusyBox版本不支持UDP
  • 其他版本?请留言!

相关但没有使用nc命名的工具有:

  • nmap: ncat -u --send-only localhost 8000 <<<hello
  • bash: echo hello >/dev/udp/localhost/8000
  • socat - UDP:localhost:8000 <<<hello
  • sendip -p ipv4 -p udp -ud 8000 -d $'hello\n' localhost
  • packetsender -ua localhost 8000 $'hello\n'
  • 还有很多其他工具!但是最初的问题是关于netcat的...

如果您需要一个便携式的nc封装程序来发送单个UDP数据包,请尝试使用以下脚本nc-udp-oneshot.sh

#!/bin/sh

helpword=$(nc -h 2>&1 | awk '{print$1;exit}')

case $helpword in
  *GNU*) args=-uc ;;
  *) args=-uq0 ;;
esac
exec nc $args "$@"

现在您可以使用安装的任何nc运行echo -n hello | ./nc-udp-oneshot.sh。或者使用xxd -r -p <<<68656c6c6f | ./nc-udp-oneshot.sh发送更复杂的二进制数据,用十六进制表示。请保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接