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选择排序算法的实现代码
Nov 21 Python
跟老齐学Python之有容乃大的list(1)
Sep 14 Python
为Python的web框架编写前端模版的教程
Apr 30 Python
在Python中操作字符串之rstrip()方法的使用
May 19 Python
Python正则捕获操作示例
Aug 19 Python
Python enumerate索引迭代代码解析
Jan 19 Python
Django如何配置mysql数据库
May 04 Python
Python wxPython库Core组件BoxSizer用法示例
Sep 03 Python
python文件转为exe文件的方法及用法详解
Jul 08 Python
Python 函数绘图及函数图像微分与积分
Nov 20 Python
python torch.utils.data.DataLoader使用方法
Apr 02 Python
详细介绍python操作RabbitMq
Apr 12 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
图书管理程序(一)
2006/10/09 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
PHP 微信支付类 demo
2015/11/30 PHP
JavaScript调用Activex控件的事件的实现方法
2010/04/11 Javascript
Javascript学习笔记二 之 变量
2010/12/15 Javascript
基于jquery步骤进度条源码分享
2015/11/12 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
2016/07/28 Javascript
Javascript 实现微信分享(QQ、朋友圈、分享给朋友)
2016/10/21 Javascript
浅析vue数据绑定
2017/01/17 Javascript
Bootstrap DateTime Picker日历控件简单应用
2017/03/25 Javascript
bootstrap daterangepicker双日历时间段选择控件详解
2017/06/15 Javascript
JS实现商品筛选功能
2020/08/19 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
2018/12/09 Javascript
Vue项目部署的实现(阿里云+Nginx代理+PM2)
2019/03/26 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
JS如何实现网站中PC端和手机端自动识别并跳转对应的代码
2020/01/08 Javascript
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
原生js+canvas实现贪吃蛇效果
2020/08/02 Javascript
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
浅谈Python3识别判断图片主要颜色并和颜色库进行对比的方法
2019/10/25 Python
wxPython+Matplotlib绘制折线图表
2019/11/19 Python
Python pip配置国内源的方法
2020/02/14 Python
python如何进行矩阵运算
2020/06/05 Python
css3 实现滚动条美化效果的实例代码
2021/01/06 HTML / CSS
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
JBL澳大利亚官方商店:扬声器、耳机和音响系统
2018/05/24 全球购物
实习生个人的自我评价
2013/12/08 职场文书
反邪教标语
2014/06/23 职场文书
大学生作弊检讨书
2014/09/11 职场文书
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
2015年百日安全活动总结
2015/03/26 职场文书
运动会闭幕式主持词
2015/07/01 职场文书
Python实现简繁体转换
2021/06/07 Python
Python排序算法之插入排序及其优化方案详解
2021/06/11 Python