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数据结构之Array用法实例
Oct 09 Python
Python安装使用命令行交互模块pexpect的基础教程
May 12 Python
Python自定义进程池实例分析【生产者、消费者模型问题】
Sep 19 Python
Python语言描述随机梯度下降法
Jan 04 Python
python数据归一化及三种方法详解
Aug 06 Python
Django密码存储策略分析
Jan 09 Python
Python如何爬取qq音乐歌词到本地
Jun 01 Python
PyInstaller运行原理及常用操作详解
Jun 13 Python
Matplotlib 折线图plot()所有用法详解
Jul 28 Python
2020版Python学习路线图(附学习资料)
Sep 15 Python
Python pathlib模块使用方法及实例解析
Oct 05 Python
pytorch中的 .view()函数的用法介绍
Mar 17 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/02 无线电
PHP把数字转成人民币大写的函数分享
2014/06/30 PHP
php求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
js控制的回到页面顶端goTop的代码实现
2013/03/20 Javascript
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
jQuery简单几行代码实现tab切换
2015/03/10 Javascript
跟我学习javascript解决异步编程异常方案
2015/11/23 Javascript
jQuery实现监控页面所有ajax请求的方法
2015/12/10 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
2016/04/29 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
JS实现环形进度条(从0到100%)效果
2016/07/05 Javascript
微信小程序中做用户登录与登录态维护的实现详解
2017/05/17 Javascript
通过js控制时间,一秒一秒自己动的实例
2017/10/25 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
2017/11/20 Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
2018/02/09 Javascript
关于ckeditor在bootstrap中modal中弹框无法输入的解决方法
2019/09/11 Javascript
vue登录注册实例详解
2019/09/14 Javascript
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
2020/05/18 Javascript
python创建关联数组(字典)的方法
2015/05/04 Python
mysql 之通过配置文件链接数据库
2017/08/12 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
2018/04/27 Python
django 自定义filter 判断if var in list的例子
2019/08/20 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
Python爬虫解析网页的4种方式实例及原理解析
2019/12/30 Python
快速解决jupyter启动卡死的问题
2020/04/10 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
2020/12/16 Python
质检部经理岗位职责
2014/02/19 职场文书
《晚上的太阳》教学反思
2014/04/23 职场文书
学术会议开幕词
2016/03/03 职场文书
【超详细】八大排序算法的各项比较以及各自特点
2021/03/31 Python
PHP实现考试倒计时功能代码
2021/04/16 PHP
Python基础之条件语句详解
2021/06/16 Python
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis
Redis实现短信验证码登录的示例代码
2022/06/14 Redis