文章目录
- 1. 按
- 2. tcping.exe
- 2.1. 下载
- 2.2. 使用方法
- 2.3. 更多帮助
- 2.3.1. Usage
- 2.3.2. Examples
- 3. Python代码
- 3.1. 使用方法
1. 按
在Windows中,系统自带的ping命令往往只能检测ICMP端口的连接情况,如果服务器开启了防火墙并且禁用了ping命令,那么我们往往就没法进行检测网络联通情况了,另外ping命令也不能针对某一特定的端口进行测试。
本文介绍的这款工具不仅可以在服务器开启了防火墙并且禁用了ping命令的情况下进行测试与主机的联通情况,而且还能指定进行测试特定的端口。
在主流的Linux系统中,通过yum或者apt也可安装tcping,不过通过源安装的tcping只能显示单次检测的结果,也没有具体的连接时延。
现在我们介绍一下tcping工具并且用Python仿写一下相关功能,以便于在Linux上或其他平台上运行。
2. tcping.exe
在Windows上,可以直接下载tcping.exe,不需要再编写代码了。
2.1. 下载
2.2. 使用方法
- 使用CMD或者PowerShell转到相应的工作目录(存储exe文件的目录)下,然后执行:
./tcping coco56.top
- 用于测试本机与
coco56.top
所解析到的服务器的联通情况。 - 如下命令用于测试本机与
114.114.114.114
这台服务器的53
号端口的连接情况
./tcping 114.114.114.114 53
- 另外为了方便使用,也可以把
tcping.exe
文件所在的目录追加到环境变量的Path值里。 - 在使用
tcping
时如需增加可选参数,请在tcping
后直接增加,始终把主机和端口字段放在命令的最后
如:
tcping -t sz.coco56.top 15273
tcping -t -6 1.coco56.top
2.3. 更多帮助
2.3.1. Usage
NAME
tcping - simulate "ping" over tcp by establishing a connection to network hosts.
Measures the time for your system to [SYN], receive the target's [SYN][ACK] and send [ACK]. Note that the travel time for
the last ACK is not included - only the time it takes to be put on the wire a tthe sending end.
SYNOPSIS
tcping [-tdsvf46] [-i interval] [-n times] [-w interval] [-b n] [-r times][-j depth] [--tee filename] [-f] destination [port]
DESCRIPTION
tcping measures the time it takes to perform a TCP 3-way handshake (SYN, SYN/ACK, ACK) between itself and a remote host.
The travel time of the outgoing final ACK is not included, only the (minimal) amount of time it has taken to drop it on
the wire at the near end. This allows the travel time of the (SYN, SYN/ACK) to approximate the travel time of the
ICMP (request, response) equivalent.
OPTIONS
-4 Prefer using IPv4
-6 Prefer using IPv6
-t ping continuously until stopped via control-c
-n count
send _count_ pings and then stop. Default 4.
-i interval
Wait _interval_ seconds between pings. Default 1. Decimals permitted.
-w interval
Wait _interval_ seconds for a response. Default 2. Decimals permitted.
-d include date and time on every output line
-f Force sending at least one byte in addition to making the connection.
-g count
Give up after _count_ failed pings.
-b type
Enable audible beeps.
'-b 1' will beep "on down". If a host was up, but now its not, beep.
'-b 2' will beep "on up". If a host was down, but now its up, beep.
'-b 3' will beep "on change". If a host was one way, but now its the other, beep.
'-b 4' will beep "always".
-c only show output on a changed state
-r count
Every _count_ pings, we will perform a new DNS lookup for the host in case it changed.
-s Exit immediately upon a success.
-v Print version and exit.
-j Calculate jitter. Jitter is defined as the difference between the last response time and the historical average.
-js depth
Calculate jitter, as with -j but with an optional _depth_ argument specified. If _depth_ is specified tcping will
use the prior _depth_ values to calculate a rolling average.
--tee _filename_
Duplicate output to the _filename_ specified. Windows can still not be depended upon to have a useful command line
environment. Don't tease me, *nix guys.
--append
When using --tee, append to rather than overwrite the output file.
--file
Treat the "destination" option as a filename. That file becomes a source of destinations, looped through on a
line by line basis. Some options don't work in this mode and statistics will not be kept.
destination
A DNS name, an IP address, or (in "http" mode) a URL.
Do not specify the protocol ("http://") in "http" mode. Also do not specify server port via ":port" syntax.
For instance: "tcping http://www.elifulkerson.com:8080/index.html" would fail
Use the style: "tcping www.elifulkerson.com/index.html 8080" instead.
port
A numeric TCP port, 1-65535. If not specified, defaults to 80.
--header
include a header with the command line arguments and timestamp. Header is implied if using --tee.
HTTP MODE OPTIONS
-h Use "http" mode. In http mode we will attempt to GET the specified document and return additional values including
the document's size, http response code, kbit/s.
-u In "http" mode, include the target URL on each output line.
--post Use POST instead of GET in http mode.
--head Use HEAD instead of GET in http mode.
--get Shorthand to invoke "http" mode for consistency's sake.
--proxy-server _proxyserver_
Connect to _proxyserver_ to request the url rather than the server indicated in the url itself.
--proxy-port _port_
Specify the numeric TCP port of the proxy server. Defaults to 3128.
--proxy-credentials username:password
Specify a username:password pair which is sent as a 'Proxy-Authorization: Basic' header.
RETURN VALUE
tcping returns 0 if all pings are successful, 1 if zero pings are successful and 2 for mixed outcome.
BUGS/REQUESTS
Please report bugs and feature requests to the author via contact information on http://www.elifulkerson.com
AVAILABILITY
tcping is available at http://www.elifulkerson.com/projects/tcping.php
2.3.2. Examples
C:\ tcping www.elifulkerson.com
Probing 64.22.103.201:80/tcp - Port is open - time=25.739ms
Probing 64.22.103.201:80/tcp - Port is open - time=21.842ms
Probing 64.22.103.201:80/tcp - Port is open - time=27.701ms
Probing 64.22.103.201:80/tcp - Port is open - time=27.489ms
Ping statistics for 64.22.103.201:80
4 probes sent.
4 successful, 0 failed.
Approximate trip times in milli-seconds:
Minimum = 21.842ms, Maximum = 27.701ms, Average = 25.693ms
C:\tcping -h www.elifulkerson.com
** Requesting "" from www.elifulkerson.com:
(for various reasons, kbit/s is an approximation)
Probing 64.22.103.201:80/tcp - HTTP is open - time=31.288ms rcv_time=31.951 status=200 bytes=4052 kbit/s=~1014.554
Probing 64.22.103.201:80/tcp - HTTP is open - time=29.553ms rcv_time=30.947 status=200 bytes=4052 kbit/s=~1047.479
Probing 64.22.103.201:80/tcp - HTTP is open - time=29.871ms rcv_time=31.727 status=200 bytes=4052 kbit/s=~1021.728
Probing 64.22.103.201:80/tcp - HTTP is open - time=29.976ms rcv_time=36.002 status=200 bytes=4052 kbit/s=~900.393
Ping statistics for 64.22.103.201:80
4 probes sent.
4 successful, 0 failed.
Approximate trip times in milli-seconds:
Minimum = 29.553ms, Maximum = 31.288ms, Average = 30.172ms
3. Python代码
tcping.py
import socket, sys
import time
import argparse
from argparse import RawTextHelpFormatter
VERSION = '1.0.1'
ping_cnt = 0
ping_success_cnt = 0
ping_fail_cnt = 0
ping_resp_min = 0
ping_resp_max = 0
ping_resp_avg = 0
ping_resp_total = 0
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
# get ip from hostname
def host2ip(host):
try:
return socket.gethostbyname(host)
except Exception:
return False
# probing tcp port
def tcp(ip, port, timeout=2):
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.settimeout(timeout)
try:
t1 = time.time()
sk.connect((ip, port))
t2 = time.time()
sk.close()
return True, int(round((t2 - t1) * 1000))
except Exception:
sk.close()
return False, timeout * 1000
def format_tcp_result(results):
if results[0]:
return "Probing {}:{}/tcp - Port is open - time={}ms".format(ip, port, results[1])
else:
return "Probing {}:{}/tcp - No response - time={}ms".format(ip, port, results[1])
def statistic_tcp_result(results):
global ping_cnt
global ping_success_cnt
global ping_fail_cnt
global ping_resp_min
global ping_resp_max
global ping_resp_avg
global ping_resp_total
# total count
ping_cnt += 1
if results[0]:
# success count
ping_success_cnt += 1
# min ping response time
if ping_resp_min == 0:
ping_resp_min = results[1]
elif results[1] < ping_resp_min:
ping_resp_min = results[1]
# max ping respose time
if results[1] > ping_resp_max:
ping_resp_max = results[1]
# average ping response time
ping_resp_avg = round((ping_resp_total + results[1]) / float(ping_success_cnt), 3)
ping_resp_total += results[1]
else:
# fail count
ping_fail_cnt += 1
return ping_cnt, ping_success_cnt, ping_fail_cnt, ping_resp_min, ping_resp_max, ping_resp_avg
if __name__ == "__main__":
desc = '''--------------------------------------------------------------------------
Please see for more introductions.
--------------------------------------------------------------------------'''
example_text = '''examples:
tcping coco56.top
tcping 114.114.114.114 -t -p 53
tcping zhangnq.com -n 10 -p 443 -i 5 -w 1
\n
'''
parser = MyParser(description=desc, formatter_class=RawTextHelpFormatter, epilog=example_text)
parser.add_argument("destination", type=str, help="a DNS name, an IP address")
parser.add_argument("-p", dest="port", type=int, default=80,
help="a numeric TCP port, 1-65535. If not specified, defaults to 80.")
parser.add_argument("-t", dest="is_continuously", action='store_true',
help="ping continuously until stopped via control-c.")
parser.add_argument("-n", dest="number", type=int, default=4, help="send count pings and then stop, default 4.")
parser.add_argument("-i", dest="interval", type=int, default=1, help="wait seconds between pings, default 1.")
parser.add_argument("-w", dest="wait", type=int, default=2, help="wait seconds for a response, default 2.")
parser.add_argument("-v", "--version", action='version', version=VERSION, help="print version and exit.")
args = parser.parse_args()
ip = host2ip(args.destination)
port = args.port
if not ip:
print("ERROR: Could not find host - %s, aborting" % args.destination)
sys.exit(1)
try:
# continuously
if args.is_continuously:
print("")
print("** Pinging continuously. Press control-c to stop **")
print("")
while True:
results = tcp(ip, port, args.wait)
# print format result
print(format_tcp_result(results))
# start statistic
statistic_tcp_result(results)
time.sleep(args.interval)
else:
print("")
for i in range(args.number):
results = tcp(ip, port, args.wait)
# print format result
print(format_tcp_result(results))
# start statistic
statistic_tcp_result(results)
time.sleep(args.interval)
except KeyboardInterrupt:
print("Control-C")
finally:
format_statistic_results = '''
Ping statistics for {}, port {}:
Probes: send = {}, success = {}, fail = {} ({}% fail)
Approximate trip times:
Minimum = {}ms, Maximum = {}ms, Average = {}ms
'''.format(ip, port, ping_cnt, ping_success_cnt, ping_fail_cnt, round(ping_fail_cnt / float(ping_cnt) * 100, 2),
ping_resp_min, ping_resp_max, ping_resp_avg)
print(format_statistic_results)
3.1. 使用方法
需要先安装好Python3环境,具体参考:
- 将源码命名为
tcping.py
- 使用CMD或者PowerShell转到相应的工作目录(存储源码文件的目录)下,然后执行:
python .\tcping.py coco56.top
用于测试本机与coco56.top
所解析到的服务器的联通情况。
- 如下命令用于测试本机与
114.114.114.114
这台服务器的53
号端口的连接情况
python .\tcping.py 114.114.114.114 -p 53
- 参数介绍
必选参数:
destination a DNS name, an IP address
可选参数:
-h, --help show this help message and exit
-p PORT a numeric TCP port, 1-65535. If not specified, defaults to 80.
-t ping continuously until stopped via control-c.
-n NUMBER send count pings and then stop, default 4.
-i INTERVAL wait seconds between pings, default 1.
-w WAIT wait seconds for a response, default 2.
-v, --version print version and exit.