python和C语言混合编程实例 最近为了测试网速情况怎么样,由于部分业务服务器需要关闭icmp,这样的话采用普通的ping就无法适应我的需求,于是自己简单的写了一个基于tcp端口的ping的程序,由于c执行效率比较的不错,但是开发效率低下,而python是开发效率高,但是执行效率不如C,由于需要大规模的使用,于是用C实现核心部分的代码,并把这部分实现成一个python的模块,由python调用c的模块,下面就贴代码吧 复制代码 代码如下:/* tcpportping.c */#include #include #include #include #include #include #include /* 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 tcpportpingimport timei = 0while 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几乎没有什么差别。