python和C语言混合编程实例


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 相关文章推荐
Python中使用strip()方法删除字符串中空格的教程
May 20 Python
python面向对象多线程爬虫爬取搜狐页面的实例代码
May 31 Python
python 提取tuple类型值中json格式的key值方法
Dec 31 Python
值得收藏的10道python 面试题
Apr 15 Python
Python redis操作实例分析【连接、管道、发布和订阅等】
May 16 Python
python numpy数组中的复制知识解析
Feb 03 Python
python属于跨平台语言码
Jun 09 Python
解决tensorflow/keras时出现数组维度不匹配问题
Jun 29 Python
Django如何使用asyncio协程和ThreadPoolExecutor多线程
Oct 12 Python
Python Web项目Cherrypy使用方法镜像
Nov 05 Python
python爬虫泛滥的解决方法详解
Nov 25 Python
Python爬虫数据的分类及json数据使用小结
Mar 29 Python
python实现的一个p2p文件传输实例
Jun 04 #Python
python实现文件分组复制到不同目录的例子
Jun 04 #Python
python实现的udp协议Server和Client代码实例
Jun 04 #Python
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
Jun 04 #Python
Python程序员鲜为人知但你应该知道的17个问题
Jun 04 #Python
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
Jun 04 #Python
python控制台英汉汉英电子词典
Apr 23 #Python
You might like
php db类库进行数据库操作
2009/03/19 PHP
PHP CodeIgniter分页实例及多条件查询解决方案(推荐)
2017/05/20 PHP
PHP number_format函数原理及实例解析
2020/07/14 PHP
静态的动态续篇之来点XML
2006/12/23 Javascript
070823更新的一个[消息提示框]组件 兼容ie7
2007/08/29 Javascript
jquery1.5.1中根据元素ID获取元素对象的代码
2011/04/02 Javascript
JavaScript自执行闭包的小例子
2013/06/29 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
利用浏览器全屏api实现js全屏
2014/01/16 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
针对初学者的jQuery入门指南
2015/08/15 Javascript
用JavaScript判断CSS浏览器类型前缀的两种方法
2015/10/08 Javascript
jQuery+php实时获取及响应文本框输入内容的方法
2016/05/24 Javascript
Document.body.scrollTop的值总为零的快速解决办法
2016/06/09 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
每周一练 之 数据结构与算法(Stack)
2019/04/16 Javascript
Node.js 路由的实现方法
2019/06/05 Javascript
jquery添加div实现消息聊天框
2020/02/08 jQuery
JavaScript中EventBus实现对象之间通信
2020/10/18 Javascript
[02:56]DOTA2上海特锦赛小组赛解说FreeAgain采访花絮
2016/02/27 DOTA
[01:02:20]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
使用Python对SQLite数据库操作
2017/04/06 Python
Python实现比较扑克牌大小程序代码示例
2017/12/06 Python
解决pip install的时候报错timed out的问题
2018/06/12 Python
Django中使用极验Geetest滑动验证码过程解析
2019/07/31 Python
Python3批量移动指定文件到指定文件夹方法示例
2019/09/02 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
django之导入并执行自定义的函数模块图解
2020/04/01 Python
初探CSS3中的calc()功能
2015/07/14 HTML / CSS
CSS的background属性及CSS3的背景图片设置总结
2016/06/13 HTML / CSS
经济管理毕业生求职信
2014/03/15 职场文书
伦敦奥运会的口号
2014/06/21 职场文书
委托证明书
2014/09/17 职场文书
2015年教务工作总结
2015/05/23 职场文书
MongoDB连接数据库并创建数据等使用方法
2021/11/27 MongoDB
浅谈css实现背景颜色半透明的两种方法
2021/12/06 HTML / CSS