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 相关文章推荐
在pandas中一次性删除dataframe的多个列方法
Apr 10 Python
Python使用matplotlib实现基础绘图功能示例
Jul 03 Python
Python中 map()函数的用法详解
Jul 10 Python
详解Python 切片语法
Jun 10 Python
简单了解python反射机制的一些知识
Jul 13 Python
Python如何实现在字符串里嵌入双引号或者单引号
Mar 02 Python
通过python调用adb命令对App进行性能测试方式
Apr 23 Python
keras在构建LSTM模型时对变长序列的处理操作
Jun 29 Python
python Cartopy的基础使用详解
Nov 01 Python
Python json解析库jsonpath原理及使用示例
Nov 25 Python
python实现三阶魔方还原的示例代码
Apr 28 Python
Python多个MP4合成视频的实现方法
Jul 16 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 高效率写法 推荐
2010/02/21 PHP
php Notice: Undefined index 错误提示解决方法
2010/08/29 PHP
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
php采用file_get_contents代替使用curl实例
2014/11/07 PHP
深入解析PHP的Yii框架中的缓存功能
2016/03/29 PHP
微信支付开发交易通知实例
2016/07/12 PHP
PHP实现图片压缩
2020/09/09 PHP
JQuery jsonp 使用示例代码
2009/08/12 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
收集的10个免费的jQuery相册
2011/02/26 Javascript
JS中判断null、undefined与NaN的方法
2014/03/26 Javascript
11种ASP连接数据库的方法
2015/09/18 Javascript
基于javascript实现窗口抖动效果
2016/01/03 Javascript
Bootstrap创建可折叠的组件
2016/02/23 Javascript
不定义JQuery插件 不要说会JQuery
2016/03/07 Javascript
html5+javascript实现简单上传的注意细节
2016/04/18 Javascript
jquery遍历table的tr获取td的值实现方法
2016/05/19 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
js实现上传并压缩图片效果
2018/01/10 Javascript
详解vue-cli3多页应用改造
2019/06/04 Javascript
浅谈vue中get请求解决传输数据是数组格式的问题
2020/08/03 Javascript
python使用多线程不断刷新网页的方法
2015/03/31 Python
Python中Random和Math模块学习笔记
2015/05/18 Python
python时间日期函数与利用pandas进行时间序列处理详解
2018/03/13 Python
Python 循环终止语句的三种方法小结
2019/06/24 Python
搭建python django虚拟环境完整步骤详解
2019/07/08 Python
Python接口自动化测试的实现
2020/08/28 Python
高清屏下canvas重置尺寸引发的问题的解决
2019/10/14 HTML / CSS
电影T恤、80年代T恤和80年代服装:TV Store Online
2020/01/05 全球购物
瑞典在互联网上最大的宠物商店:Animail
2020/10/31 全球购物
TCP协议通讯的过程和步骤是什么
2015/10/18 面试题
室内设计专业个人的自我评价
2013/12/18 职场文书
自愿解除劳动合同协议书
2014/09/11 职场文书
创先争优演讲稿
2014/09/15 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
Python 中random 库的详细使用
2021/06/03 Python