最近因工作需要,研究批量tcp port ping。在网上看到一个测试单个IP的脚本,遂将脚本改造了一下,实现批量的tcpportping。这个脚本ping目标IP和端口6次,去掉最大值,然后取5次的平均值。

共3个文件:Tcportping.py、tcpportping.c和tcpportping.so(根据tcpportping.c生成);

需要安装python-devel

[root@***** ]# more tcpportping.c 
/* tcpportping.c */ 
#include </usr/include/python2.6/Python.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <sys/time.h> 
   
/* count time functions */ 
static double mytime(void) 
{ 
    struct timeval tv; 
    if (gettimeofday(&tv, NULL) == -1) 
        return 0.0; 
   
    return (double)tv.tv_usec + (double)tv.tv_sec * 1000; 
} 
   
static PyObject *                                 /* returns object */ 
tcpping(PyObject *self, PyObject *args ) 
{ 
    struct  sockaddr_in addr; 
    struct  hostent *hp; 
    double  time; 
    char    *host = NULL; 
    int     fd; 
    int     port, timeout; 
   
    if (!PyArg_ParseTuple(args, "sii", &host, &port, &timeout))  /* convert Python -> C */ 
        return NULL;                              /* null=raise exception */ 
   
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 
        return Py_BuildValue("d", -1.0);        /* convert C -> Python */ 
    } 
   
    bzero((char *)&addr, sizeof(addr)); 
    if ((hp = gethostbyname(host)) == NULL) { 
        return Py_BuildValue("d", -2.0);        /* convert C -> Python */ 
    } 
    bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
   
    struct timeval tv; 
   
    tv.tv_sec = 0; 
    tv.tv_usec = timeout * 1000; 
   
    double stime = mytime(); 
    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { 
        return Py_BuildValue("d", -3.0);        /* convert C -> Python */ 
    } 
    fd_set read, write; 
    FD_ZERO(&read); 
    FD_ZERO(&write); 
   
    FD_SET(fd, &read); 
    FD_SET(fd, &write); 
   
    if (select(fd + 1, &read, &write, NULL, &tv) == 0) { 
        close(fd); 
        return Py_BuildValue("d", -4.0);        /* convert C -> Python */ 
    } 
   
    double etime = mytime(); 
    time = etime - stime; 
    if (!FD_ISSET(fd, &read) && !FD_ISSET(fd, &write)) { 
        close(fd); 
        return Py_BuildValue("d", -4.0);        /* convert C -> Python */ 
    } 
    close(fd); 
    return Py_BuildValue("d", time/1000);        /* convert C -> Python */ 
} 
   
/* registration table  */ 
static struct PyMethodDef portping_methods[] = { 
    {"tcpping", tcpping, METH_VARARGS},       /* method name, C func ptr, always-tuple */ 
    {NULL, NULL}                   /* end of table marker */ 
}; 
   
/* module initializer */ 
void inittcpportping( )                       /* called on first import */ 
{                                      /* name matters if loaded dynamically */ 
    (void) Py_InitModule("tcpportping", portping_methods);   /* mod name, table ptr */ 
}





# 生成tcpportping.so 
[root@**** ]#  gcc -fpic -shared tcpportping.c -o tcpportping.so

# 主程序内容
[root@***** ~]# more Tcportping.py
#!/usr/bin/python2

import tcpportping
iplist=file('/root/iplist.txt')

ip=[]
port=[]
domain=[]
location=[]
for line in iplist.readlines():
        new_line=line.split()
        ip.append(new_line[0])
        port.append(new_line[1])
        domain.append(new_line[2])
        location.append(new_line[3])

#print ip
#print port
for i in range(len(ip)):
        Delay = [tcpportping.tcpping(ip[(i)], int(port[(i)]), 100),]
        Delay.append(tcpportping.tcpping(ip[(i)], int(port[(i)]), 100))
        Delay.append(tcpportping.tcpping(ip[(i)], int(port[(i)]), 100))
        Delay.append(tcpportping.tcpping(ip[(i)], int(port[(i)]), 100))
        Delay.append(tcpportping.tcpping(ip[(i)], int(port[(i)]), 100))
        Delay.append(tcpportping.tcpping(ip[(i)], int(port[(i)]), 100))
#       print Delay
        Delay.remove(max(Delay))
#       print Delay
        t = reduce(lambda x,y:x+y,Delay)/5
#       print t
        print domain[(i)]+","+location[(i)]+","+ip[(i)]+","+port[(i)]+","+str(t)
        
# 从文件中读取要ping的目的IP和端口,格式为:

111.161.60.55   2099      英雄联盟           天津联通      
125.39.200.43   2099      英雄联盟           天津联通      
125.39.200.44   8443      英雄联盟           天津联通

# 执行后输出的结果:也可以修改print格式成任何格式。
[root@nxttBC ~]# ./Tcportping.py
英雄联盟,天津联通,111.161.60.55,2099,21.585
英雄联盟,天津联通,125.39.200.43,2099,22.1576
英雄联盟,天津联通,125.39.200.44,8443,21.7886

# 也可以将结果重定向保存为文件