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 相关文章推荐
pycharm 使用心得(二)设置字体大小
Jun 05 Python
Python中的条件判断语句基础学习教程
Feb 07 Python
Python基础语法(Python基础知识点)
Feb 28 Python
Python编程生成随机用户名及密码的方法示例
May 05 Python
基于windows下pip安装python模块时报错总结
Jun 12 Python
Python Web框架之Django框架文件上传功能详解
Aug 16 Python
使用matplotlib绘制图例标签中带有公式的图
Dec 13 Python
使用Pytorch来拟合函数方式
Jan 14 Python
python实现俄罗斯方块小游戏
Apr 24 Python
python中pandas对多列进行分组统计的实现
Jun 18 Python
Python采集爬取京东商品信息和评论并存入MySQL
Apr 12 Python
python在package下继续嵌套一个package
Apr 14 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
咖啡界又出新概念,无需咖啡豆的分子咖啡
2021/03/03 咖啡文化
php一次性删除前台checkbox多选内容的方法
2013/09/22 PHP
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
java模拟PHP的pack和unpack类
2016/04/13 PHP
PHP简单判断手机设备的方法
2016/08/23 PHP
Jquery ThickBox插件使用心得(不建议使用)
2010/09/08 Javascript
jQuery1.6 正式版发布并提供下载
2011/05/05 Javascript
jQuery ajax 路由和过滤器使用说明
2011/08/02 Javascript
js中replace的用法总结
2013/12/27 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
jQuery实现将div中滚动条滚动到指定位置的方法
2016/08/10 Javascript
整理一下常见的IE错误
2016/11/18 Javascript
浅谈ECMAScript6新特性之let、const
2017/08/02 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
ES6学习教程之模板字符串详解
2017/10/09 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
使用Vue生成动态表单
2019/11/26 Javascript
Vue的Eslint配置文件eslintrc.js说明与规则介绍
2020/02/03 Javascript
vue router-link 默认a标签去除下划线的实现
2020/11/06 Javascript
Python验证码识别处理实例
2015/12/28 Python
python实现域名系统(DNS)正向查询的方法
2016/04/19 Python
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
解决安装python库时windows error5 报错的问题
2018/10/21 Python
python实现差分隐私Laplace机制详解
2019/11/25 Python
Python中三维坐标空间绘制的实现
2020/09/22 Python
HomeAway的巴西品牌:Alugue Temporada
2018/04/10 全球购物
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
印度尼西亚手表和包包商店:Urban Icon
2019/12/12 全球购物
教师党员思想汇报
2014/01/06 职场文书
校长先进事迹材料
2014/02/01 职场文书
幼儿园家长评语
2014/02/10 职场文书
感恩节红领巾广播稿
2014/02/11 职场文书
诚实守信道德模范事迹材料
2014/08/15 职场文书
2014国庆节国旗下演讲稿(精选版)
2014/09/26 职场文书
2015年度优秀员工获奖感言
2015/07/31 职场文书
table设置超出部分隐藏,鼠标移上去显示全部内容的方法
2022/12/24 HTML / CSS