使用Python统计端口TCP连接数

发布时间:2019-09-10 09:13:37编辑:auto阅读(1925)

        此脚本可以用来统计某个端口上连接的IP的数量,统计连接到这一端口的所有IP、最多的IP和次数以及TCP连接状态。

        涉及到Python读取网络连接统计信息以及统计计算的一些基本操作。在编写脚本的过程中预先定义了统计信息的数据结构,在向最终结果中添加统计信息时需要用到list去重功能,因此临时创建了一个列表使用set()函数去重。set()函数不能直接add字典类型,因此先将字典转成可哈希的字符串,再将去重后的字符串转成字典。其中字典、列表和集合都属于不可哈希的类型。

        此脚本可以用于Windows、Linux以及OSX,其中OSX上运行需要使用root权限(由于psutil的原因),使用时直接使用python运行此脚本文件即可。如果提示‘ImportError’,则使用pip安装所缺的模块,非特权用户使用pip安装模块时需要使用sudo。

        脚本内已经设定port为22,可以自己修改代码,使它允许成接收命令行位置参数或者手动输入。

    运行效果图如下:

    1.使用root用户运行

    p_w_picpath 

    2.使用非特权用户运行

    p_w_picpath

    脚本文件可以通过GitHub获取:https://github.com/DingGuodong/LinuxBashShellScriptForOps/blob/master/functions/net/tcp/port/portStatistics.py

    脚本内容如下:

    #!/usr/bin/python
    # encoding: utf-8
    # -*- coding: utf8 -*-
    """
    Created by PyCharm.
    File:               LinuxBashShellScriptForOps:portStatistics.py
    User:               Guodong
    Create Date:        2016/10/27
    Create Time:        10:51
    
    Note:
        Usage:
        Using user as you want in Linux/Windows system.
        The python module 'psutil' and 'prettytable' is required, using pip
        install them.
        ```
        pip install psutil prettytable
        ```
        On OSX this function requires root privileges.
    
        # python portStatistics.py
        Total connections of port 22 is 10.
        +--------------+-------------------+-------------------+-----------------+--------------+
        | Total Counts | Remote IP Address | Established Conns | Time_wait Conns | Others Conns |
        +--------------+-------------------+-------------------+-----------------+--------------+
        |      5       |     10.6.28.46    |         5         |        0        |      0       |
        |      1       |     10.6.28.35    |         1         |        0        |      0       |
        |      1       |     10.6.28.27    |         1         |        0        |      0       |
        |      2       |    10.6.28.135    |         2         |        0        |      0       |
        |      1       |    10.6.28.125    |         1         |        0        |      0       |
        +--------------+-------------------+-------------------+-----------------+--------------+
        Elapsed time: 0.0104579925537 seconds.
        #
    
     """
    
    import psutil
    import prettytable
    import time
    
    startTime = time.time()
    
    port = 22  # ssh -i /etc/ssh/ssh_host_rsa_key root@10.6.28.28
    
    # define data structure for each connection, each ip is unique unit
    ipaddress = {
        'ipaddress': None,
        'counts': 0,
        'stat': {
            'established': 0,
            'time_wait': 0,
            'others': 0
        }
    }
    
    # define data structure for statistics
    statistics = {
        'portIsUsed': False,
        'portUsedCounts': 0,
        'portPeerList': [
            {
                'ipaddress': None,
                'counts': 0,
                'stat': {
                    'established': 0,
                    'time_wait': 0,
                    'others': 0
                },
            },
        ]
    }
    
    tmp_portPeerList = list()
    portPeerSet = set()
    netstat = psutil.net_connections()
    
    # get all ip address only for statistics data
    for i, sconn in enumerate(netstat):
    
        if port in sconn.laddr:
            statistics['portIsUsed'] = True
            if len(sconn.raddr) != 0:
                statistics['portUsedCounts'] += 1
                ipaddress['ipaddress'] = sconn.raddr[0]
                tmp_portPeerList.append(str(ipaddress))  # dict() list() set() is unhashable type, collections.Counter
    
    for ip in tmp_portPeerList:
        portPeerSet.add(str(ip))  # remove duplicated ip address using set()
    
    for member in portPeerSet:
        statistics['portPeerList'].append(eval(member))
    
    # add statistics data for each ip address
    for sconn in netstat:
        if port in sconn.laddr:
            if len(sconn.raddr) != 0:
                for i, item in enumerate(statistics['portPeerList']):
                    if item['ipaddress'] == sconn.raddr[0]:
                        statistics['portPeerList'][i]['counts'] += 1
                        if sconn.status == 'ESTABLISHED':
                            statistics['portPeerList'][i]['stat']['established'] += 1
                        elif sconn.status == 'TIME_WAIT':
                            statistics['portPeerList'][i]['stat']['time_wait'] += 1
                        else:
                            statistics['portPeerList'][i]['stat']['others'] += 1
    
    # print statistics result using prettytable
    if statistics['portIsUsed']:
        print "Total connections of port %s is %d." % (port, statistics['portUsedCounts'])
        table = prettytable.PrettyTable()
        table.field_names = ["Total Counts", "Remote IP Address", "Established Conns", "Time_wait Conns",
                             "Others Conns"]
        for i, ip in enumerate(statistics['portPeerList']):
            if ip['ipaddress'] is not None:
                table.add_row([ip['counts'], ip['ipaddress'], ip['stat']['established'], ip['stat']['time_wait'],
                               ip['stat']['others']])
        print table.get_string(sortby=table.field_names[1], reversesort=True)
    else:
        print 'port %s has no connections, please make sure port is listen or in use.' % port
    
    endTime = time.time()
    print "Elapsed time: %s seconds." % (endTime - startTime)

    tag:端口统计,python TCP连接数统计,Python统计连接数

    --end--

关键字