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正则表达式
Jan 15 Python
Python日期的加减等操作的示例
Aug 15 Python
python爬取各类文档方法归类汇总
Mar 22 Python
pycharm执行python时,填写参数的方法
Oct 29 Python
Python基于plotly模块实现的画图操作示例
Jan 23 Python
python实现简单五子棋游戏
Jun 18 Python
python set内置函数的具体使用
Jul 02 Python
Python tkinter和exe打包的方法
Feb 05 Python
在keras下实现多个模型的融合方式
May 23 Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 Python
python两种注释用法的示例
Oct 09 Python
Pytest之测试命名规则的使用
Apr 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
如何去掉文章里的 html 语法
2006/10/09 PHP
PHP计划任务之关闭浏览器后仍然继续执行的函数
2010/07/22 PHP
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
php获取从百度搜索进入网站的关键词的详细代码
2014/01/08 PHP
主流PHP框架的优缺点对比分析
2014/12/25 PHP
Nigma vs Liquid BO3 第二场2.13
2021/03/10 DOTA
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
Javascript 定时器调用传递参数的方法
2009/11/12 Javascript
JavaScript中instanceof与typeof运算符的用法及区别详细解析
2013/11/19 Javascript
三种检测iPhone/iPad设备方向的方法
2014/04/23 Javascript
JS实现网页表格自动变大缩小的方法
2015/03/09 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
分析js闭包引起的事件注册问题
2016/03/29 Javascript
浏览器兼容的JS写法总结
2016/04/27 Javascript
jQuery常用样式操作实例分析(获取、设置、追加、删除、判断等)
2016/09/08 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
在Vue中如何使用Cookie操作实例
2017/07/27 Javascript
JQuery 选择器、DOM节点操作练习实例
2017/09/28 jQuery
javascript标准库(js的标准内置对象)总结
2018/05/26 Javascript
更改BootStrap popover的默认样式及popover简单用法
2018/09/13 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
node实现socket链接与GPRS进行通信的方法
2019/05/20 Javascript
vue 父组件通过$refs获取子组件的值和方法详解
2019/11/07 Javascript
微信小程序实现上传多张图片、删除图片
2020/07/29 Javascript
Vue中 axios delete请求参数操作
2020/08/25 Javascript
Python编程产生非均匀随机数的几种方法代码分享
2017/12/13 Python
Python如何访问字符串中的值
2020/02/09 Python
HTML5之多线程(Web Worker)
2019/01/02 HTML / CSS
纯HTML5+CSS3制作生日蛋糕(代码易懂)
2016/11/16 HTML / CSS
New Balance德国官方网站:购买鞋子和服装
2019/08/31 全球购物
旅游管理毕业生自荐信
2013/11/05 职场文书
初中生物教学反思
2014/01/10 职场文书
年度考核自我鉴定
2014/02/02 职场文书
ES6 解构赋值的原理及运用
2021/05/25 Javascript
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android
mysql 体系结构和存储引擎介绍
2022/05/06 MySQL