netcat实用程序的替代方案



是否有其他netcat实用程序?我想运行docker API和netcat实用程序没有安装在客户端系统上。docker命令示例- echo -e "GET/info HTTP/1.0rn" | nc - u/var/run/docker.sock

据此,

(exec 3<>/dev/tcp/url/port; cat >&3; cat <&3; exec 3<&-)

可以代替nc/netcat。它应该可以在任何基于bash的终端中工作。

的例子:

printf "Hello World!" | (exec 3<>/dev/tcp/termbin.com/9999; cat >&3; cat <&3; exec 3<&-)

返回一个链接

socatncnetcat的一个更强大的版本。

你有Perl吗?你可以这样做:

perl -MLWP::Simple -e "getprint('http://localhost')"

遵循Python中创建套接字连接并以tcp和udp发送数据的实现:

import socket
def netcat(hostname, port, content=None, protocol='tcp'):
    print('')
    if protocol == 'tcp':
        s = socket.socket() # (socket.AF_INET, socket.SOCK_STREAM)
    if protocol == 'udp':
        s = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    if protocol != 'tcp' and protocol != 'udp':
        print("Error: Protocol must be 'tcp' or 'udp'")
    try:
        s.connect((hostname, port))
        print('Connection Success to ' + hostname + ':' + str(port) + '/' + protocol)
    except:
        print('Connection failed to ' + hostname + ':' + str(port) + '/' + protocol)
        return None
    if content != None:
        print('Starting to send content: ' + str(content))
        s.send(str.encode(content))
        # s.sendall(content)
        hasHacievedAnyData = False
        while True:
            s.settimeout(10)
            try:
                data = s.recv(1024)
            except Exception:
                if hasHacievedAnyData:
                    print('Info: Timeout while expecting to receve more data')
                else:
                    print('Error: Timeout while expecting to receve data')
                break
            if len(data) == 0:
                break
            print('Received:' + str(repr(data)))
            hasHacievedAnyData = True
        s.shutdown(socket.SHUT_WR)
        s.close()
        print('Connection closed.')
#Examples of usage
netcat('localhost', 443)
netcat('localhost', 3478)
netcat('localhost', 3478, protocol='udp')
netcat('localhost', 16384, 'Hello', 'udp')

现在Python无处不在,socket模块就是你所需要的。

下面是一些例子:您可以使用它来测试端口443到3个主机列表的连通性:

import socket
def test_socket(ip,port):
        s = socket.socket()
        try:
            s.settimeout(3)
            s.connect((ip,port))
        except socket.error as msg:
            s.close()
            print 'could not open %s:%s %s' % (ip,port,msg)
            return(1)
        else:
            s.close()
            print '%s:%s is OK' % (ip,port)
            return(0)

hosts=['host1.example.com','host2.example.com','host3.example.com']
for host in hosts:
   print "testing %s 443" % host
   test_socket(host,443)

这一行可以读取stdin或文件,并在端口9999上发送到主机名termbin.com,上传文件到termbin:

 python -c "import socket,fileinput;  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(('termbin.com', 9999)) ; [ s.send(b) for b in fileinput.input() ]; print s.recv(1024); s.close();" filetoupload.txt

bash和perl的一些方法:

# bash nc-connect (1-way sender)
echo "test" >/dev/tcp/localhost/1234
# perl nc-listen (1-way receiver)
perl -MIO::Socket::INET -e '$l=IO::Socket::INET->new(LocalPort=>1234,Proto=>"tcp",Listen=>5,ReuseAddr=>1);$l=$l->accept;while(<$l>){print}'
- adapted from https://unix.stackexchange.com/questions/49936/dev-tcp-listen-instead-of-nc-listen

# perl nc-connect (2-way) one-liner
perl -MFcntl=F_SETFL,F_GETFL,O_NONBLOCK -MSocket '-e$0=perl;socket($c,AF_INET,SOCK_STREAM,0)&&connect($c,sockaddr_in$ARGV[1],inet_aton$ARGV[0])||die$!;fcntl$_,F_SETFL,O_NONBLOCK|fcntl$_,F_GETFL,0 for@d=(*STDIN,$c),@e=($c,*STDOUT);L:for(0,1){sysread($d[$_],$f,8**5)||exit and$f[$_].=$f if vec$g,$_*($h=fileno$c),1;substr$f[$_],0,syswrite($e[$_],$f[$_],8**5),"";vec($g,$_*$h,1)=($i=length$f[$_]<8**5);vec($j,$_||$h,1)=!!$i}select$g,$j,$k,5;goto L' localhost 1234
- https://www.perlmonks.org/?node_id=942861
(see perlmonks site for readable full-length version)
# perl nc-listen (2-way) one-liner
perl -e 'use strict;use IO::Select;use IO::Socket;my ($data,$fh);my $s=IO::Select->new();my $l=new IO::Socket::INET(Listen=>5,LocalAddr=>$ARGV[0],LocalPort=>$ARGV[1],Proto=>"tcp");$s->add(*STDIN);print "listening...n";my $incoming=$l->accept;$s->add($incoming);print "incoming...n";while(1){if(my @ready=$s->can_read(.01)){foreach $fh (@ready){if ($fh==*STDIN) {my $data=<STDIN>;$incoming->send($data)}else{$fh->recv($data,1024);if($data eq ""){print "closedn";$s->remove($fh);$fh->close;exit;}else{print "$data";}}}}}' localhost 1234
- heavily adapted from: https://www.perlmonks.org/?node_id=49823
(see below for readable full-length version)

# perl nc-listen (1-way sender)
perl -MIO::Socket::INET -ne 'BEGIN{$l=IO::Socket::INET->new(LocalPort=>1234,Proto=>"tcp",Listen=>5,ReuseAddr=>1);$l=$l->accept}print $l $_' <file
- https://unix.stackexchange.com/questions/49936/dev-tcp-listen-instead-of-nc-listen
# perl nc-connect(1-way receiver) (similar to: cat </dev/tcp/localhost/1234)
perl -MIO::Socket::INET -e '$s=IO::Socket::INET->new(PeerAddr=>"localhost",PeerPort=>1234,Proto=>"tcp");while(<$s>){print}'

任何类型的监听操作都需要bind+accept调用,这在bash中使用/dev/tcp无法完成。任何类型的双向IO都需要某种非阻塞IO方法,如select

可读的完整版本的perl nc-listen (2-way);(可随意修改)

#!/usr/bin/perl -w
use strict;
use IO::Select;
use IO::Socket;
my ($data, $fh);
my $s = IO::Select->new();
my $l = new IO::Socket::INET(Listen => 5, LocalAddr => 'localhost', LocalPort => 6089, Proto => "tcp");
$s->add(*STDIN);
print "listening...n";
my $incoming = $l->accept;
$s->add($incoming);
print "incoming connection...n";
while (1) {
    if (my @ready = $s->can_read(.01)) {
        foreach $fh (@ready) {
            if ($fh == *STDIN) {
                my $data=<STDIN>;
                $incoming->send($data);
            } else {
                $fh->recv($data, 1024);
                if($data eq "") {
                    print "connection closedn";
                    $s->remove($fh);
                    $fh->close;
                    exit;
                } else {
                    print "$data";
                }
            }
        }
    }
}

相关:用于测试docker/docker-compose端口映射

# docker-compose.yml : dummy port-test container
version: "3.9"
services:
   test:
        container_name:test
        image: debian
        #network_mode: host
        ports:
            - 6000:6000
        #extra_hosts:
            #- "host.docker.internal:host-gateway"
docker-compose run --service-ports -it test bash
docker run -p 6000:6000 -it debian bash : run debian directly with port-mapping
docker exec -it CONTAINER_ID bash : open a second command prompt
docker ps -a : shows mapped ports
To test port mapping: put a nc-listen receiver inside the container and run a
nc-connect from the host-os (`echo "test" >/dev/tcp/localhost/1234`).
# check port mapping
sudo iptables -L -v -n | less
# docker-proxy is run once for each host-mapped-port-direction
ps auwx | grep docker-proxy
network_mode:host puts container ports right on the host and does not map them
extra_hosts makes host.docker.internal work in linux

最新更新