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

5

34

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

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.

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

(Note: The server won't close 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.)

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

Diluvial answered 13/8, 2009 at 4:27 Comment(1)
Is &001C a 16 bit Unicode codepoint or is it just the ASCII character 0x1C ?Sympathizer
S
16

Create a bash script called client.sh:

#!/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:

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

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

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.

Sympathizer answered 13/8, 2009 at 5:16 Comment(1)
Commenting on an old answer, but my version of nc (1.10) needs -e instead of -c (and then this works nicely for me). Also, a nit-pick: I'd avoid invoking printf each time through the loop, preferring to set a variable to the regular expression once. For example: re=$'.*\x1C.*' ... then use [[ $FOO =~ $re ]] as the conditional.Before
D
11

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.

Demolish answered 14/6, 2015 at 10:25 Comment(1)
How did I get the bounty, when the highest voted answer is not mine, & there is no accepted answer?Demolish
D
7

Try:

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

This requires 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.

Deft answered 13/8, 2009 at 16:40 Comment(2)
This won't work because netcat will close the connection as soon as cat closes netcat's standard input.Sympathizer
fixed, with a timeout even :)Deft
V
3

Maybe have a look at Ncat as well:

"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."

http://nmap-ncat.sourceforge.net

Variegate answered 13/8, 2009 at 16:32 Comment(0)
H
3

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

while read i; do 
    if [ "$i" = "0x1c" ] ; then # Read until "0x1c". Then exit
        break
    fi
    echo $i; 
done < <(cat someFile | netcat somehost 1234)
Harter answered 7/8, 2015 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.