所以,我最近发现了如何通过/dev/tcp/hostname/port文件发送 TCP 数据包,但我的主要问题是我如何接收它们。我想制作一个可以托管 TCP 服务器的 bash 脚本,以及另一个作为 TCP 客户端的脚本。一些帮助会很棒。我还想指出,我这样做是作为一种学习体验,这就是为什么我不使用ssh或telnet作为执行我想要的任务的方式。
根据这个,没有。你不能这样做,因为bash不尝试bind(2)套接字,而只是尝试connect(2).
您可以通过以下几种方式启动netcat服务器:
(我使用nmap'sncat因为GNUnc自 2004 年以来没有看到更新)
local $ :|{ ncat -l 9999 --keep-open --allow localhost |
local > PS1='ncat $ ' PS2='ncat > ' dash +m -i 2>&1
local > } 1<>/dev/fd/0
[1] + Running : | { ncat -l 9999 --keep-open --allow localhost | PS1='ncat $ ' PS2='ncat > ' dash +m -i 2>&1; } 1<>/dev/fd/0
Run Code Online (Sandbox Code Playgroud)
我:|在那里借用了管道 -dash写出来并ncat读取它,因为:null 命令肯定不需要它。有时比mkfifo.
无论如何,关键是ncat写入的所有内容都通过管道传输到dash的标准输入,而dash写入的所有内容都通过管道传输到ncat的标准输入。不是bash,我知道,但我会做到的。但请注意,至少,该+m选项。
local $ ncat localhost 9999
ncat $ echo $0 $$
dash 31231
ncat $ ls -l /dev/fd/[012]
lr-x------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/0 -> pipe:[3563412]
l-wx------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/1 -> pipe:[3567682]
l-wx------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/2 -> pipe:[3567682]
ncat $ ^C
local $
Run Code Online (Sandbox Code Playgroud)
我必须使用 ,+m因为一个-monitored 作业控制的 shell - 通常默认情况下为交互式 shell 设置为 on -i- 会尝试从其控制终端读取并发送一个SIGTTIN- 默认情况下会自动挂起它,或者否则(如果它试图忽略或阻止它)杀死它。
[1] + Stopped(SIGTTIN) : | { ncat -l 9999 | dash -i 2>&1; } 1<>/dev/fd/0
Run Code Online (Sandbox Code Playgroud)
但是这里没有终端——这些只是管道,正如你在ls输出中看到的那样——所以-m监控是不行的。
bash碰巧,即使readline禁用了它,它的初始交互式终端关联似乎也不那么灵活。
[1] + Stopped(SIGTTIN) : | { ncat -l 9999 | bash --noediting +m -i 2>&1 ; } 1<>/dev/fd/0
Run Code Online (Sandbox Code Playgroud)
那么该怎么办?好吧,我们需要一个伪终端。类似于我们在模拟器中拥有的东西。
local $ ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/0 -> /dev/pts/0
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/1 -> /dev/pts/0
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/2 -> /dev/pts/0
Run Code Online (Sandbox Code Playgroud)
我们可以从/dev/ptmxlinux 系统上的主设备获取一个(尽管tty如果您不想先chown成为该组的成员,您的用户可能需要成为该组的成员)。如果我们< open(2)使用 ptmx 设备,将创建一个新的伪终端,如果我们之后创建unlockpt(3)了新的设备文件,我们就可以读取和写入它。
前段时间我了解到使用 shell 并没有真正简单的方法来做到这一点,所以我为它编写了一个小 C 程序。您会在该链接中找到一些解释和简单的构建说明(实际上只是复制/粘贴到 shell 提示中) - 这是pts我在下面使用的程序。
local $ { 9>&- setsid -c -- bash <> "$({ pts &&
local > >&9 ncat -l 9999 -k --allow localhost
local > } <&9 &)" 2>&0 >&2 ; } 9<> /dev/ptmx
local $
Run Code Online (Sandbox Code Playgroud)
有一个在伪终端上bash作为会话领导者启动,它pts解锁并命名其标准输出 - 替代<>重定向中的标准bash。但是,显然什么都没有发生,因为所有的 i/o 都在别处 - 到新的伪终端 - 唯一的链接是ncat在端口 9999 上启动的服务器。-i这里bash不需要交互式开关 -将自动在它自己的 pty。
local $ ncat localhost 9999
[mikeserv@desktop ~]$ echo hey
echo hey
hey
[mikeserv@desktop ~]$ ls -l /dev/fd/[012]
ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/0 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/1 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/2 -> /dev/pts/4
[mikeserv@desktop ~]$ ^[[A^[[A
Run Code Online (Sandbox Code Playgroud)
好吧,我们快到了。所以我们肯定有一个 socketized- bash,但可能你注意到那里奇怪的双回声,最后一个提示中有趣的转义实际上是我按下了 ^up 箭头键。这里的问题是我们有两层伪终端——我的ncat客户端运行stty echo的一层设置为与服务器运行的一层相同。并且因为客户端是面向行的,并且每个输入换行符刷新一次输出,并且还根据默认stty echoctl设置打印 ctrl-char 转义符,所以bash根本不会收到 ^up 箭头键,我们只看到有趣的小逃亡。
好的。我们也可以处理。
local $ ncatsh()(
local > ${2+":"} set localhost "${1:?ncatsh(): No port number provided!}"
local > stty=" stty -F'$(tty)'" || unset stty
local > trap " ${stty- ncat '${1##*\'*}' '${2##*\'*}' </dev/null} \
local > ${stty+$(for a in -g 'raw -echo isig intr "^A" quit "" susp ""'
local > do eval "$stty $a";done)}
local > trap - 0 1 2; exit" 0 1 2
local > ncat "$@"
local > )
Run Code Online (Sandbox Code Playgroud)
该函数将检查它的标准输入是否是一个终端——你的本地终端——如果不是,它只会将输入传递给ncat客户端。但如果是这样,它会trap在退出时发出EXIT、HANGUP和INTERRUPT信号以恢复其标准的终端状态。这是一件好事,因为它也会在调用标准输入之前改变该状态ncat。
本地回声被禁用,本地终端设置为原始模式 - 因此每次按键都会ncat立即发送到服务器。事实上,所有特殊的本地模式键都被禁用,除了本地intr - 通常是CTRL+C,但在这里配置为CTRL+A- 因为CTRL+C将由bash服务器解释。
我会再做ls一次,但只需按 ^up 箭头然后RETURN。
local $ ncatsh 9999
[mikeserv@desktop ~]$ ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/0 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/1 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/2 -> /dev/pts/4
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$
local $
Run Code Online (Sandbox Code Playgroud)
你在那里看不到它,因为按下时本地回显被禁用,但我按下CTRL+A中断会话并返回本地提示,此时所有本地终端配置都恢复到权限。该bash服务器遗体,不过,ncatsh 9999会带我右后卫,如果我将它。
为了简化您的工作,请尝试使用“netcat”工具。它可以用作服务器或客户端,并且能够发送和接收任意数据。
那就不用费心处理低级的东西了..
#server listening on port 8000/tcp
$>netcat -l 8000
#client sending stuff to localhost 8000/tcp
$>netcat localhost 8000
blah
Run Code Online (Sandbox Code Playgroud)