bash 在响应中返回某个字符后,如何关闭 netcat 连接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1270027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:24:28  来源:igfitidea点击:

How can I close a netcat connection after a certain character is returned in the response?

linuxbashnetcat

提问by SCdF

We have a very simple tcp messaging script that cats some text to a server port which returns and displays a response.

我们有一个非常简单的 tcp 消息传递脚本,它将一些文本发送到服务器端口,该端口返回并显示响应。

The part of the script we care about looks something like this:

我们关心的脚本部分看起来像这样:

cat someFile | netcat somehost 1234

The response the server returns is 'complete' once we get a certain character code (specifically &001C) returned.

一旦我们得到返回的某个字符代码(特别是&001C),服务器返回的响应就是“完整的” 。

How can I close the connection when I receive this special character?

当我收到这个特殊字符时如何关闭连接?

(Note: The server won'tclose the connection for me. While I currently just CTRL+C the script when I can tell it's done, I wish to be able to send many of these messages, one after the other.)

(注意:服务器不会为我关闭连接。虽然我目前只是 CTRL+C 脚本,当我知道它已经完成时,我希望能够一个接一个地发送这些消息中的许多。)

(Note: netcat -w xisn't good enough because I wish to push these messages through as fast as possible)

(注意:netcat -w x还不够好,因为我希望尽快推送这些消息)

回答by caf

Create a bash script called client.sh:

创建一个名为 client.sh 的 bash 脚本:

#!/bin/bash

cat someFile

while read FOO; do
        echo $FOO >&3
        if [[ $FOO =~ `printf ".*\x00\x1c.*"` ]]; then
                break
        fi
done

Then invoke netcat from your main script like so:

然后从您的主脚本调用 netcat ,如下所示:

3>&1 nc -c ./client.sh somehost 1234

(You'll need bash version 3 for the regexp matching).

(您需要 bash 版本 3 才能进行正则表达式匹配)。

This assumes that the server is sending data in lines - if not you'll have to tweak client.sh so that it reads and echoes a character at a time.

这假设服务器正在按行发送数据 - 如果不是,您将不得不调整 client.sh 以便它一次读取和回显一个字符。

回答by anishsane

How about this?

这个怎么样?

Client side:

客户端:

awk -v RS=$'\x1c' 'NR==1;{exit 0;}'  < /dev/tcp/host-ip/port

Testing:

测试:

# server side test script
while true; do ascii -hd; done | { netcat -l 12345; echo closed...;}
# Generate 'some' data for testing & pipe to netcat.
# After netcat connection closes, echo will print 'closed...'

# Client side:
awk -v RS=J 'NR==1; {exit;}' < /dev/tcp/localhost/12345
# Changed end character to 'J' for testing.
# Didn't wish to write a server side script to generate 0x1C.

Client side produces:

客户端产生:

    0 NUL    16 DLE    32      48 0    64 @    80 P    96 `   112 p
    1 SOH    17 DC1    33 !    49 1    65 A    81 Q    97 a   113 q
    2 STX    18 DC2    34 "    50 2    66 B    82 R    98 b   114 r
    3 ETX    19 DC3    35 #    51 3    67 C    83 S    99 c   115 s
    4 EOT    20 DC4    36 $    52 4    68 D    84 T   100 d   116 t
    5 ENQ    21 NAK    37 %    53 5    69 E    85 U   101 e   117 u
    6 ACK    22 SYN    38 &    54 6    70 F    86 V   102 f   118 v
    7 BEL    23 ETB    39 '    55 7    71 G    87 W   103 g   119 w
    8 BS     24 CAN    40 (    56 8    72 H    88 X   104 h   120 x
    9 HT     25 EM     41 )    57 9    73 I    89 Y   105 i   121 y
   10 LF     26 SUB    42 *    58 :    74

After 'J' appears, server side closes & prints 'closed...', ensuring that the connection has indeed closed.

'J' 出现后,服务器端关闭并打印 'closed...',确保连接确实已关闭。

回答by bdonlan

Try:

尝试:

(cat somefile; sleep $timeout) | nc somehost 1234 | sed -e '{s/\x01.*//;T skip;q;:skip}'

This requires GNU sed.

这需要GNU sed。

How it works:

这个怎么运作:

{
    s/\x01.*//; # search for \x01, if we find it, kill it and the rest of the line
    T skip;     # goto label skip if the last s/// failed
    q;          # quit, printing current pattern buffer
    :skip       # label skip
}

Note that this assumes there'll be a newline after \x01 - sed won't see it otherwise, as sed operates line-by-line.

请注意,这假设 \x01 之后会有一个换行符 - 否则 sed 不会看到它,因为 sed 逐行运行。

回答by bdonlan

Maybe have a look at Ncat as well:

也许也看看 Ncat:

"Ncat is the culmination of many key features from various Netcat incarnations such as Netcat 1.x, Netcat6, SOcat, Cryptcat, GNU Netcat, etc. Ncat has a host of new features such as "Connection Brokering", TCP/UDP Redirection, SOCKS4 client and server supprt, ability to "Chain" Ncat processes, HTTP CONNECT proxying (and proxy chaining), SSL connect/listen support, IP address/connection filtering, plus much more."

“Ncat 是 Netcat 1.x、Netcat6、SOcat、Cryptcat、GNU Netcat 等各种 Netcat 版本的许多关键功能的结晶。Ncat 具有许多新功能,例如“连接代理”、TCP/UDP 重定向、 SOCKS4 客户端和服务器支持、“链接”Ncat 进程的能力、HTTP CONNECT 代理(和代理链接)、SSL 连接/侦听支持、IP 地址/连接过滤等等。”

http://nmap-ncat.sourceforge.net

http://nmap-ncat.sourceforge.net

回答by Gabriel Le Roux

This worked best for me. Just read the output with a while loop and then check for "0x1c" using an if statement.

这对我来说效果最好。只需使用 while 循环读取输出,然后使用 if 语句检查“0x1c”。

while read i; do 
    if [ "$i" = "0x1c" ] ; then # Read until "0x1c". Then exit
        break
    fi
    echo $i; 
done < <(cat someFile | netcat somehost 1234)

回答by tomheron

This works great:

这很好用:

echo ^C | nc -v 29.7.144.21 1364

See output below:

请参阅下面的输出:

[root@localhost ~]# echo ^C | nc -v 29.7.144.21 1364 Ncat: Version 6.40 ( http://nmap.org/ncat) Ncat: Connected to 29.7.144.21:1364. ^C Ncat: 3 bytes sent, 0 bytes received in 0.01 seconds.

[root@localhost ~]#

[root@localhost ~]# echo ^C | nc -v 29.7.144.21 1364 Ncat:版本 6.40 ( http://nmap.org/ncat) Ncat:连接到 29.7.144.21:1364。^C Ncat:发送 3 个字节,0.01 秒内接收 0 个字节。

[root@localhost ~]#