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随机生成彩票号码的方法
Mar 05 Python
python创建和删除目录的方法
Apr 29 Python
Python代码块批量添加Tab缩进的方法
Jun 25 Python
根据DataFrame某一列的值来选择具体的某一行方法
Jul 03 Python
Python实现字典按key或者value进行排序操作示例【sorted】
May 03 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
Jun 28 Python
Python3内置模块之base64编解码方法详解
Jul 13 Python
Flask框架学习笔记之模板操作实例详解
Aug 15 Python
python3 xpath和requests应用详解
Mar 06 Python
Django分组聚合查询实例分享
Apr 29 Python
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
May 31 Python
Python Matplotlib绘制两个Y轴图像
Apr 13 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
《破坏领主》销量已超100万 未来将继续开发新内容
2020/03/08 其他游戏
php的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
JQuery EasyUI 加载两次url的原因分析及解决方案
2014/08/18 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
jQuery点击其他地方时菜单消失的实现方法
2016/04/22 Javascript
javascript 分号总结及详细介绍
2016/09/24 Javascript
canvas的神奇用法
2017/02/03 Javascript
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
2017/04/21 jQuery
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
node通过npm写一个cli命令行工具
2017/10/12 Javascript
利用vue.js把静态json绑定bootstrap的table方法
2018/08/28 Javascript
vue中nextTick用法实例
2019/09/11 Javascript
JavaScript实现拖拽效果
2020/03/16 Javascript
vue实现购物车列表
2020/06/30 Javascript
深度解读vue-resize的具体用法
2020/07/08 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
Vue实现简单的留言板
2020/10/23 Javascript
django文档学习之applications使用详解
2018/01/29 Python
Python中enumerate()函数编写更Pythonic的循环
2018/03/06 Python
为什么Python中没有&quot;a++&quot;这种写法
2018/11/27 Python
用python3 urllib破解有道翻译反爬虫机制详解
2019/08/14 Python
Python绘制热力图示例
2019/09/27 Python
Matlab中plot基本用法的具体使用
2020/07/17 Python
俄罗斯香水和化妆品网上商店:NOTINO.ru
2019/12/17 全球购物
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
写好自荐信的要点
2013/11/06 职场文书
董事长助理岗位职责
2014/02/18 职场文书
新年联欢会主持词
2014/03/27 职场文书
地方白酒代理协议书
2014/10/25 职场文书
2015医德医风个人工作总结
2015/04/02 职场文书
商务司机岗位职责
2015/04/10 职场文书
幽灵公主观后感
2015/06/09 职场文书
windows11怎么查看自己安装的版本号? win11版本号的查看方法
2021/11/21 数码科技
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏