最近因工作需要,研究批量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 # 也可以将结果重定向保存为文件