Posted in Python onJune 04, 2014
最近为了测试网速情况怎么样,由于部分业务服务器需要关闭icmp,这样的话采用普通的ping就无法适应我的需求,于是自己简单的写了一个基于tcp端口的ping的程序,由于c执行效率比较的不错,但是开发效率低下,而python是开发效率高,但是执行效率不如C,由于需要大规模的使用,于是用C实现核心部分的代码,并把这部分实现成一个python的模块,由python调用c的模块,下面就贴代码吧
/* tcpportping.c */ #include <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 * 1000000; } 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 */ }
编译成python模块
gcc tcpportping.c -I/usr/include/python2.4 -shared -L/usr/bin -fpic -lpython2.4 -o tcpportping.so
下面是python调用c模块的代码:
#!/usr/bin/env pythonimport tcpportping import time i = 0 while i < 5: t = tcpportping.tcpping('www.baidu.com', 80, 1000) if t < 0: print "time out" else: print t time.sleep(0.5) i += 1
执行python代码就可以实现端口ping的结果,从测试的情况来看,该程序执行的结果跟普通的ping几乎没有什么差别。
python和C语言混合编程实例
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@