当前位置:  互联网>综合
本页文章导读:
    ▪网络中的网关技术      网关(Gateway)又称网间连接器、协议转换器。网关在传输层上实现网络互联,是最复杂的网络互联设备,仅用于两个高层协议不同的网络互联。网关既可以用于广域互联网,也可以用于局域.........
    ▪使用http_parser解析URL      用C语言编写http应用,解析URL是一个繁琐的事儿。前几天使用http_parser实现httpclient,发现里面提供了一个解析URL的方法http_parser_parse_url,用起来相当方便。 http_parser_parse_url通过分析URL字符串,.........
    ▪处理nginx实时日志生成另一个实时日志      一.背景介绍 1.知识点 写这篇blog,主要有下面几个知识点想介绍: curl获取http相应内容; shell中执行php文件; php中执行shell命令(通过exec函数); php实现tail -f命令; 包含空格的参数如何.........

[1]网络中的网关技术
    来源: 互联网  发布时间: 2013-10-24

网关(Gateway)又称网间连接器、协议转换器。网关在传输层上实现网络互联,是最复杂的网络互联设备,仅用于两个高层协议不同的网络互联。网关既可以用于广域互联网,也可以用于局域互联网。网关是一种担负转换重任的计算机系统或设备。在使用不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。大多数网关运行在OSI 7层协议的顶层 --应用层。

在物联网系统中,信息最终都需要通过网络传输到服务器上,以便进行后续的处理和管理。通常需要网关讲信息从检测节点传输到网络上。在设计网关时,可以采用两种方式:有线方式和无线方式。有线方式是在信息检测节点上设计网络接口(一般是使用以太网接口芯片),通过网络接口将信息传输到网络上。无线方式目前用的较多的是使用GPRS或者使用无线接收模块接收信息,然后使用以太网接口芯片将信息传输到网络上。

提到物联网时,不得不提到已经发展了几十年的网络控制系统。网络控制系统(NCS),又称为网络化的控制系统,是在网络环境下实现的控制系统,是在网络环境下实现的控制系统,是指在某个区域内一些现场检测、控制及操作设备和通信线路的集合,用以提供设备之间的数据传输,使该区域内不同地点的设备和用户实现资源共享和协调操作。除此之外,广义的网络控制系统还包括通过企业信息网络以及Internet实现对工厂车间、生产线甚至现场设备的监视与控制等。它的一般定义是指通过计算机网络和总线将传感器、执行器和控制单元作为网络系统连接起来共同完成控制任务的系统。典型的网络控制系统结构图如图1所示。

                                              图1  典型的网络控制系统结构框图

从某种意义上讲,可以将网络控制系统作为物联网的一个子集。因此,网路控制系统中的概念和技术同样可以应用到物联网中。

如果以单片机作为检测和控制中心,组成网络控制系统时,需要单片机具有以太网接口或者使用单片机外接以太网口或者使用单片机外接以太网接口的组合方式。典型结构如图2所示。

                                       图2  以单片机为检测和控制中心的网络控制系统结构框图

其中,节点2、……、节点N与节点1具有类似的结构。

网络控制系统(NCS)是随着控制技术、网络通信技术以及计算机技术的发展而逐渐发展起来的,其主要

优点是系统连线少、可靠性高、结构灵活、易于系统扩展和维护以及能够实现信息资源共享等。网络控制系统应用日趋广泛。

--节选自《物联网智能网关设计与应用》

 

 

作者:WIZnet2012 发表于2013-5-20 13:17:07 原文链接
阅读:101 评论:0 查看评论

    
[2]使用http_parser解析URL
    来源: 互联网  发布时间: 2013-10-24

用C语言编写http应用,解析URL是一个繁琐的事儿。前几天使用http_parser实现httpclient,发现里面提供了一个解析URL的方法http_parser_parse_url,用起来相当方便。

http_parser_parse_url通过分析URL字符串,把port、host、path、schema之类的信息保存在一个结构体http_parser_url中。通过看头文件和源码,发现这个结构体仅仅是记录了URL中各部分信息的起始位置、长度,没有做任何内存拷贝,效率上看还是不错的。目前支持SCHEMA、PORT、HOST、PATH、QUERY、USERINFO、FRAGMENT七种信息的提取。

http_parser_url定义如下:

struct http_parser_url {
  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */
  uint16_t port;                /* Converted UF_PORT string */

  struct {
    uint16_t off;               /* Offset into buffer in which field starts */
    uint16_t len;               /* Length of run in buffer */
  } field_data[UF_MAX];
};

其中,field_set成员用于检测解析到了哪种信息(使用位与操作),field_data存放相应的URL信息在原始URL中的起始位置和长度。

http_parser_parse_url()方法的原型:

int http_parser_parse_url(const char *buf, size_t buflen,
                          int is_connect,
                          struct http_parser_url *u);

需要说明的是is_connect参数,当传1时,http_parser_parse_url方法将进行严格检验,如果URL中没有port、schema将导致http_parser_parse_url方法失败,返回非0值。一般给is_connect方法传0即可。

下面是我使用的一段代码:

static int parse_url(/blog_article/struct http_client _ httpc, const char _url/index.html)
{
    struct http_parser_url u;
    if(0 == http_parser_parse_url(url, strlen(url), 0, &u))
    {
        if(u.field_set & (1 << UF_PORT))
        {
            httpc->port = u.port;
        }
        else
        {
            httpc->port = 80;
        }
        
        if(httpc->host) free(httpc->host);
        if(u.field_set & (1 << UF_HOST) )
        {
            httpc->host = (char*)malloc(u.field_data[UF_HOST].len+1);
            strncpy(httpc->host, url+u.field_data[UF_HOST].off, u.field_data[UF_HOST].len);
            httpc->host[u.field_data[UF_HOST].len] = 0;
        }

        if(httpc->path) free(httpc->path);
        if(u.field_set & (1 << UF_PATH))
        {
            httpc->path = (char*)malloc(u.field_data[UF_PATH].len+1);
            strncpy(httpc->path, url+u.field_data[UF_PATH].off, u.field_data[UF_PATH].len);
            httpc->path[u.field_data[UF_PATH].len] = 0;
        }

        return 0;
    }

    return -1;
}

上面的代码是我实现的http_client中的一部分,仅供参考。


作者:foruok 发表于2013-5-21 12:58:49 原文链接
阅读:56 评论:0 查看评论

    
[3]处理nginx实时日志生成另一个实时日志
    来源: 互联网  发布时间: 2013-10-24
一.背景介绍 1.知识点

写这篇blog,主要有下面几个知识点想介绍:

curl获取http相应内容;

shell中执行php文件;

php中执行shell命令(通过exec函数);

php实现tail -f命令;

包含空格的参数如何作为参数传递(用双引号括起来)。


2.业务流程

这篇blog的背景是读取"/data3/im-log/nginx.im.imp.current/nginx.im.imp.current_current"这个实时日志,生成招聘会所需的实时日志。


业务流程如下:
(1)从http://bj.baidu.com/jobfairs/jobfairs_im_port.php?action=getIms获取企业和IM客户端id的关系。
响应的格式如下:
{"status":1,"ret":{"company_id":{“im_accout”:[im_id],"company_name":[]}}}
获取到的数据如下:
{"status":1,"ret":{"2028107":{"im_account":["31669394","50000098"],"name":["baidu"]},"2028098":{"im_account":["50029298","50000098","31669376","31669394","50006271"],"name":["sogou"]}},"msg":""}

这里碰到的第一个问题是我开发所在的环境和http://bj.baidu.com不在同一个网段内,该url服务所在的IP为10.3.255.201,此时我需要进行hosts映射,这样当我访问http://bj.baidu.com/jobfairs/jobfairs_im_port.php?action=getIms时,便相当于我在访问了http://10.3.255.201/jobfairs/jobfairs_im_port.php?action=getIms。
但是我们一定有一个疑问,为什么我们不直接使用http://10.3.255.201/jobfairs/jobfairs_im_port.php?action=getIms来进行访问,答案是我们需要通过url获取到用户的城市,即http://bj.baidu.com/jobfairs/jobfairs_im_port.php?action=getIms,这里面包含bj.baidu.com,包含用户的城市信息bj。

解决方法是通过curl对url和host进行映射:

curl -H "Host: bj.ganji.com" http://10.3.255.201/jobfairs/jobfairs_im_port.php?action=getIms

参考链接:http://blog.csdn.net/lianxiang_biancheng/article/details/7575370  中的curl命令的使用。

(2)其次,如果这条日志记录中fromUserId或者toUserId包含某个企业的IM客户端id,则说明这条消息属于这个企业;

(3)最后,生成所需格式的日志,日志的字段格式如下:
时间 企业Id 企业名称 企业IM的id  应聘者IM的id 谁发送的信息(0:企业,1:应聘者)  消息内容

二.采用了三种实现方式 1.第一种:shell读取每一行传递给php进行匹配并输出 (1)start.sh是启动文件,如下:

#!/bin/sh

#执行前清除所有该进程
pids=`ps aux | grep jobfairs | grep -v "grep" | awk '{print $2}'`      
if [ "$pids" != "" ];then 
    echo $pids
    kill -9 $pids
fi
sh jobfairs.sh >> /home/baidu/log/jobfairs.log

(2)jobfairs.sh是获取http内容,读取实时日志并每2分钟重新请求的实现,如下:

#!/bin/sh

logfile="/data3/im-log/nginx.im.imp.current/nginx.im.imp.current_current"

hours=`date +%H`
start_time=`date +%s`

#17点后停止运行程序
while [ $hours -lt 17 ]
do
    res=`curl -s -H "Host: bj.baidu.com" http://10.3.255.201/jobfairs/jobfairs_im_port.php?action=getIms`
    #echo $res
    
    len=${#res}
    if [ $len = 0 ]; then
        echo "Failed! Request error!"
        exit
    fi

    status=`echo $res | sed -e 's/.*status"://' -e 's/,.*//'`
    if [ $status != 1 ]; then 
        echo "Failed! Request stauts:"$status
        exit
    fi

    ret=`echo $res | sed -e 's/.*ret"://' -e 's/,"msg.*//'`
    #ret='{"2028097":{"im_account":["2875001357","197823104","3032631861","197305863"],"name":["8\u811a\u732b\u521b\u65b0\u79d1\u6280\u6709\u9650\u516c\u53f8\uff08\u4e60\u5927\u7237\u6dae\u8089\u5bf9\u976210000\u7c73\u7684\u79d1\u6280\u516c\u53f8\uff09"]},"2028098":{"im_account":["3658247660","192683241","197488883","108963206","197305001"],"name":["9\u811a\u732b\u521b\u65b0\u79d1\u6280\u6709\u9650\u516c\u53f8"]}}';

    tail -f $logfile | grep sendMsgOk | grep "spamReasons=\[\]" | awk -F"\t" '{
        printf("%s\t%s\t%s\t%s\n",$1,$3,$4,$11); 
    }' | while read line
    do
        /usr/local/webserver/php/bin/php jobfairs.php $ret "$line"
        
        #120s后停止生成日志,重新执行http请求去获取公司相关信息
        end_time=`date +%s`
        if [ $(expr $end_time - $start_time) -ge 120 ]; then
            #echo `date +%T`" "`date +%D`
            #echo "120s is done!"
            break
        fi
    done
    
    start_time=`date +%s`
    hours=`date +%H`
done
这里还涉及到一个知识点,就是如何将包含空格的字符串作为参数传递。
这里的场景是这样的:由于一行记录各个字段是以制表符分隔的,其中有一个字段msgContent是消息内容,而消息中经常包含空格,而php接受外来参数默认是以空格分隔的,这样如果将$line作为参数进行传递,就导致msgContent被分隔为了好几个字段。那我们如何解决这个问题呢,答案就是通过加双引号(即将$line变为"$line"),将一行记录作为一个整体字符串传入即可,然后php接收到这个字符串后,再通过explode("\t",$line)进行分隔出各个字段。如下所示:        
/usr/local/webserver/php/bin/php jobfairs.php $ret "$line" 

(3)jobfairs.php是对实时日志的每一行进行匹配并输出为IM的log格式:

<?php
    $ret = $_SERVER["argv"][1];
    $arr = json_decode($ret, true);//将json字符串解码成数组
    foreach ($arr as $key => $value) {
        $name = $value["name"][0];//企业名称
        foreach ($value["im_account"] as $v) { //企业对应的叮咚id
            $userId[$v] = $key;
            $compName[$v] = $name;
            //echo $key ."\t" . $v ."\t" . $name ."\n";
        }
    }
  
    $line = $_SERVER["argv"][2];//获取日志的一条记录
    $logArr = explode("\t", $line);
    //echo $line . "\n";

    //获取各个字段
    $time = $logArr[0];
    $fromUserId = $logArr[1];
    $toUserId = $logArr[2];
    $msgContent = $logArr[3];
    
    $fuiArr = explode('=', $fromUserId);
    $tuiArr = explode('=', $toUserId);
    $fui = $fuiArr[1];
    $tui = $tuiArr[1];

    $output = $time . "\t";
    if(isset($userId[$fui])) { //fromUserId是某个企业的叮咚id
        //echo $line . "\n";
        $output .= "companyId=$userId[$fui]\t";
        $output .= "companyName=$compName[$fui]\t";
        $output .= "companyDingdongId=$fui\t";
        $output .= "personalDingdongId=$tui\t";
        $output .= "whoSend=0\t";
        $output .= $msgContent;
        echo $output . "\n";
    } else if(isset($userId[$tui])) { //toUserId是某个企业的叮咚id
        //echo $line . "\n";
        $output .= "companyId=$userId[$tui]\t";
        $output .= "companyName=$compName[$tui]\t";
        $output .= "companyDingdongId=$tui\t";
        $output .= "personalDingdongId=$fui\t";
        $output .= "whoSend=1\t";
        $output .= $msgContent;
        echo $output . "\n";
    }
?>

2.第二种:php执行shell命令并将输出结果进行匹配

注:该方法不能生成实时日志,因为tail -f命令是实时获取更新命令,php无法获取其返回结果。所以该方法仅用于读取一段固定文本并进行处理。

这里通过exec执行tail -n1000这个shell命令,获取到最后1000行数据然后再进行处理。同时,这里还调用了php中curl模块获取http响应内容。该文件名为jobfairs2.php。

<?php
    //error_reporting(E_ALL & ~E_NOTICE);

    $host = array("Host: bj.baidu.com");
    $data = 'user=xxx&qq=xxx&id=xxx&post=xxx';
    $url = 'http://10.3.255.201/jobfairs/jobfairs_im_port.php?action=getIms';
    $res = curl_post($host, $data, $url);
   
    $arr = json_decode($res, true);
    $status = $arr["status"];

    if ($status != 1) {
        echo "Request Failed!";
        exit;
    }
    
    //获取返回的企业信息
    $ret = $arr["ret"];
    foreach ($ret as $key => $value) {
        $name = $value["name"][0];
        //将IM的Id和企业id进行hash映射
        foreach ($value["im_account"] as $v) {
            $userId[$v] = $key;
            $compName[$v] = $name;
        }
    }
    
    $logfile = "/data3/im-log/nginx.im.imp.current/nginx.im.imp.current_current";
    
    //tail -n1000获取最后1000行记录,并保存到$log变量中
    $shell = "tail -n 1000 $logfile | grep sendMsgOk | grep 'spamReasons=\[\]' | ";
    $shell .= "awk -F'\t' '{print $1,$3,$4,$11;}'";
    exec($shell, $log); //将      
    
最新技术文章:
▪用户及权限基础 2---- Linux权限    ▪用户及权限基础 3---- Linux扩展权限    ▪git 简明教程(1) --创建及提交
▪背包 代码    ▪json对象的封装与解析    ▪01背包,完全背包,多重背包 ,模板代码
▪apache安装详解    ▪HDU 4668 Finding string (解析字符串 + KMP)    ▪《TCP-IP详解 卷1:协议》学习笔记(二)
▪《TCP-IP详解 卷1:协议》学习笔记(持续更新...    ▪windows下使用swig    ▪gensim试用
▪Linux Shell脚本编程--nc命令使用详解    ▪solr对跨服务器表联合查询的配置    ▪递归和非递归实现链表反转
▪Linux磁盘及文件系统管理 1---- 磁盘基本概念    ▪Cholesky Decomposition    ▪HTTP协议学习
▪用C语言写CGI入门教程    ▪用hdfs存储海量的视频数据的设计思路    ▪java多线程下载的实现示例
▪【原创】eAccelerator 一个锁bug问题跟踪    ▪hadoop学习之ZooKeeper    ▪使用cuzysdk web API 实现购物导航类网站
▪二维数组中的最长递减子序列    ▪内嵌W5100的网络模块WIZ812MJ--数据手册    ▪xss 跨站脚本攻击
▪RobotFramework+Selenium2环境搭建与入门实例    ▪什么是API    ▪用PersonalRank实现基于图的推荐算法
▪Logtype    ▪关于端口号你知道多少!    ▪Linux基本操作 1-----命令行BASH的基本操作
▪CI8.7--硬币组合问题    ▪Ruby on Rails 学习(五)    ▪如何使用W5300实现ADSL连接(二)
▪不允许启动新事务,因为有其他线程正在该会...    ▪getting start with storm 翻译 第六章 part-3    ▪递归求排列和组合(无重复和有重复)
▪工具类之二:RegexpUtils    ▪Coding Interview 8.2    ▪Coding Interview 8.5
▪素因子分解 Prime factorization    ▪C# DllImport的用法    ▪图的相关算法
▪Softmax算法:逻辑回归的扩展    ▪最小生成树---Kruskal算法---挑战程序设计竞赛...    ▪J2EE struts2 登录验证
▪任意两点间的最短路径---floyd_warshall算法    ▪Sqoop实现关系型数据库到hive的数据传输    ▪FFMPEG采集摄像头数据并切片为iPhone的HTTP Stream...
▪Ubuntu 13.04 – Install Jetty 9    ▪TCP/IP笔记之多播与广播    ▪keytool+tomcat配置HTTPS双向证书认证
▪安装phantomjs    ▪Page Redirect Speed Test    ▪windows media player 中播放pls的方法
▪The TCP three-way handshake (connect)/four wave (closed)    ▪网站反爬虫    ▪Log4j实现对Java日志的配置全攻略 iis7站长之家
▪The TCP three-way handshake (connect)/four wave (closed)    ▪网站反爬虫    ▪Log4j实现对Java日志的配置全攻略
▪Bit Map解析    ▪Notepad 快捷键 大全    ▪Eclipse 快捷键技巧 + 重构
▪win7 打开防火墙端口    ▪Linux Shell脚本入门--awk命令详解    ▪Linux Shell脚本入门--Uniq命令
▪Linux(Android NDK)如何避免僵死进程    ▪http Content-Type一览表    ▪Redis实战之征服 Redis + Jedis + Spring (二)
▪Tomcat7.0.40 基于DataSourceRealm的和JDBCRealm的资源...    ▪利用SQOOP将ORACLE到HDFS    ▪django输出 hello world
▪python re    ▪unity3D与网页的交互    ▪内存共享基本演示
▪python join    ▪不再为无限级树结构烦恼,且看此篇    ▪python实现变参
▪打开文件数限制功能不断地制造问题    ▪Arduino Due, Maple and Teensy3.0 的 W5200性能测试    ▪Selenium实例----12306网站测试
▪基于协同过滤的推荐引擎    ▪C4.5决策树    ▪C#HTTP代理的实现之注册表实现
▪nosql和关系型数据库比较?    ▪如何快速比较这两个字符串是否相等?    ▪hdoj 1863 畅通工程 最小生成树---prime算法
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3