是否有其他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<&-)
返回一个链接
socat
是nc
和netcat
的一个更强大的版本。
你有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