参考:P4语言快速开始 感谢杨老师的分享!

前言及P4程序请参考原文,本文主要是对文章中的两个动手实例的实践记录。

1.通过behavioral-model运行simple_router样例

执行命令:

cd p4factory/targets/simple_router
make bm
sudo ./behavioral-model

在本地启动一个behavior-model,默认使用PD RPC服务的地址为127.0.0.1:9090

当在同一台宿主机上启动多个bmv2时,可以使用--pd-server=IP:PORT指定不同的端口,以防止端口占用冲突。更多参数可以使用-h参数查看CLI帮助。

执行./behavioral-model之后显示如下:

Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 2 length 107; first bytes:
33330000 00fffffffbfffffffaffffffcb ffffffaf6d3effffff8c ffffff86ffffffdd600b
new packet, len : 107, ingress : 2
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb924000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 0 length 107; first bytes:
33330000 00fffffffb1213 ffffff91ffffffdefffffffe30 ffffff86ffffffdd6008
new packet, len : 107, ingress : 0
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb928000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 6 length 107; first bytes:
33330000 00fffffffbfffffffa51 fffffff66e382d ffffff86ffffffdd600e
new packet, len : 107, ingress : 6
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb91c000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 1 length 107; first bytes:
33330000 00fffffffb1effffffee 1943ffffffc0ffffffb8 ffffff86ffffffdd6003
new packet, len : 107, ingress : 1
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb934000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 7 length 107; first bytes:
33330000 00fffffffb3e7a ffffffb10bffffff97ffffffe8 ffffff86ffffffdd600a
new packet, len : 107, ingress : 7
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb920000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 4 length 107; first bytes:
33330000 00fffffffbffffff92ffffffe4 4a34ffffff9fffffffeb ffffff86ffffffdd600b
new packet, len : 107, ingress : 4
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb914000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 5 length 107; first bytes:
33330000 00fffffffb2e33 672a7cffffffef ffffff86ffffffdd600f
new packet, len : 107, ingress : 5
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb918000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 0 length 107; first bytes:
33330000 00fffffffb4a23 66ffffffe1724a ffffff86ffffffdd600d
new packet, len : 107, ingress : 0
rmt proc returns 0
Packet in on port 6 length 107; first bytes:
33330000 00fffffffbffffffde59 680dffffffc046 ffffff86ffffffdd600e
new packet, len : 107, ingress : 6
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb928000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb91c000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 2 length 107; first bytes:
33330000 00fffffffbffffffd2ffffffd8 19ffffffce47ffffff99 ffffff86ffffffdd6009
new packet, len : 107, ingress : 2
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb924000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 3 length 107; first bytes:
33330000 00fffffffbfffffff6ffffffdb 21fffffffbffffffa97f ffffff86ffffffdd600d
new packet, len : 107, ingress : 3
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb930000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 4 length 107; first bytes:
33330000 00fffffffbffffffdaffffffec ffffffd4ffffff8fffffffed33 ffffff86ffffffdd600a
new packet, len : 107, ingress : 4
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb914000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
Packet in on port 5 length 107; first bytes:
33330000 00fffffffb1221 447dffffffd3ffffff94 ffffff86ffffffdd6006
new packet, len : 107, ingress : 5
rmt proc returns 0
ingress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
one checksum is incorrect
Applying table ipv4_lpm
Lookup key for ipv4_lpm:
ipv4_dstAddr: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
total length for outgoing meta: 24
copying metadata
deparsing standard_metadata
deparsing routing_metadata
queuing system: packet dequeued
egress port set to 0
instance type set to 0
egress_pipeline: packet dequeued
parsing start
parsing parse_ethernet
payload length: 93
extracting metadata
extracting all metadata for 0x7fb918000940
Applying table send_frame
Lookup key for send_frame:
standard_metadata_egress_port: 0x00000000,
table miss, applying default action
no default action, doing nothing
total length for outgoing pkt: 107
deparsing ethernet
outgoing thread: packet dequeued
outgoing thread: sending pkt: Size[107]: Port[0]
In client_init

之后运行./run_cli.bash脚本,访问simple_router的运行时API:

root@FZUSDNLab:/home/sdn/p4factory/targets/simple_router# ./run_cli.bash
Using default thrift server and port localhost:9090
(Cmd) ? Documented commands (type help <topic>):
========================================
EOF dump_table mc_node_destroy
add_entry exit mc_node_update
add_entry_with_member get_first_entry_handle modify_entry
add_entry_with_selector get_next_entry_handles quit
add_member help set_default_action
add_member_to_group mc_associate_node show_actions
create_group mc_dissociate_node show_entry
delete_entry mc_mgrp_create show_tables
delete_group mc_mgrp_destroy
delete_member mc_node_create (Cmd)

2.通过run_demo.bash脚本 运行启动simple_router示例

注:如果之前进行了第一步,请重启再重新开启虚拟端口,方法是进入p4factory/tools目录下,执行:

./veth_setup.sh

进入simple_router目录,执行run_demo.bash脚本使用mininet构建网络拓扑:

./run_demo.bash

执行后效果如下:

root@FZUSDNLab:/home/sdn/p4factory/targets/simple_router# ./run_demo.bash
*** Creating network
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller *** Starting 1 switches
s1 Starting P4 switch s1
/home/sdn/p4factory/targets/simple_router/behavioral-model --name s1 --dpid 0000000000000001 -i s1-eth1 -i s1-eth2 --listener 127.0.0.1:11111 --pd-server 127.0.0.1:22222
switch has been started **********
h1
default interface: eth0 10.0.0.10 00:04:00:00:00:00
**********
**********
h2
default interface: eth0 10.0.1.10 00:04:00:00:00:01
**********
Ready !
*** Starting CLI:
mininet>

注意,此时PD服务端口不再是9090,直接运行run_cli.bash脚本无法访问simple_router的运行时CLI。

有两种方法解决这个问题,一种是修改bash脚本,这里请参照原文。

另外一种是直接采用-c参数指定端口号,笔者采用的是这种方法:

./run_cli.bash -c 127.0.0.1:22222

效果如下:

root@ubuntu:/home/wasdns/p4factory/targets/simple_router# ./run_cli.bash -c 127.0.0.1:22222
(Cmd)

查看此时P4交换机中的流表:

(Cmd) show_tables
forward
ipv4_lpm
send_frame
(Cmd) dump_table forward
No entry handle found
(Cmd) dump_table ipv4_lpm
No entry handle found
(Cmd) dump_table send_frame
No entry handle found
(Cmd)

此时P4交换机中有三张流表,但是都没有内容。

证明了在只有数据平面的情况下,不同host之间是没有办法正常通信的。此时也有两种方法充当控制平面。

(1)通过运行run_add_demo_entries.bash脚本下发流表。其内容如下:

python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry send_frame 1 rewrite_mac 00:aa:bb:00:00:00" -c localhost:22222
python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry send_frame 2 rewrite_mac 00:aa:bb:00:00:01" -c localhost:22222
python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry forward 10.0.0.10 set_dmac 00:04:00:00:00:00" -c localhost:22222
python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry forward 10.0.1.10 set_dmac 00:04:00:00:00:01" -c localhost:22222
python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry ipv4_lpm 10.0.0.10 32 set_nhop 10.0.0.10 1" -c localhost:22222
python ../../cli/pd_cli.py -p simple_router -i p4_pd_rpc.simple_router -s $PWD/tests/pd_thrift:$PWD/../../testutils -m "add_entry ipv4_lpm 10.0.1.10 32 set_nhop 10.0.1.10 2" -c localhost:22222

执行./run_add_demo_entries.bash为P4交换机增添表项。

执行之后如下:

Inserted entry with handle 0
Inserted entry with handle 1
Inserted entry with handle 0
Inserted entry with handle 1
Inserted entry with handle 0
Inserted entry with handle 1

在CLI中查看流表:

1.forward:

(Cmd) dump_table forward
Entry handle 0
key:
routing_metadata_nhop_ipv4: 0x0a00000a (10 0 0 10),
action:
set_dmac
action data:
dmac: 0x000400000000,
Entry handle 1
key:
routing_metadata_nhop_ipv4: 0x0a00010a (10 0 1 10),
action:
set_dmac
action data:
dmac: 0x000400000001,
(Cmd)

2.ipv4_lpm

(Cmd) dump_table ipv4_lpm
Entry handle 0
key:
ipv4_dstAddr: 0x0a00000a (10 0 0 10),
prefix_length:
32
action:
set_nhop
action data:
nhop_ipv4: 0x0a00000a (10 0 0 10), port: 0x00000001 (0 0 0 1),
Entry handle 1
key:
ipv4_dstAddr: 0x0a00010a (10 0 1 10),
prefix_length:
32
action:
set_nhop
action data:
nhop_ipv4: 0x0a00010a (10 0 1 10), port: 0x00000002 (0 0 0 2),
(Cmd)

3.send_frame

(Cmd) dump_table send_frame
Entry handle 0
key:
standard_metadata_egress_port: 0x00000001 (0 0 0 1),
action:
rewrite_mac
action data:
smac: 0x00aabb000000,
Entry handle 1
key:
standard_metadata_egress_port: 0x00000002 (0 0 0 2),
action:
rewrite_mac
action data:
smac: 0x00aabb000001,
(Cmd)

在mininet中能够ping通:

(2)编写command.txt,并通过behavioral-model/tools/runtimeCLI下发流表。

在运行之前,请先安装bmv2(behavioral-model),可以参考我的另外一篇博客:P4 前端编译器p4c-bm、后端编译器bmv2命令安装 make error问题

command.txt内容如下:

table_set_default send_frame _drop
table_set_default forward _drop
table_set_default ipv4_lpm _drop
table_add send_frame rewrite_mac 1 => 00:aa:bb:00:00:00
table_add send_frame rewrite_mac 2 => 00:aa:bb:00:00:01
table_add forward set_dmac 10.0.0.10 => 00:04:00:00:00:00
table_add forward set_dmac 10.0.1.10 => 00:04:00:00:00:01
table_add ipv4_lpm set_nhop 10.0.0.10/32 => 10.0.0.10 1
table_add ipv4_lpm set_nhop 10.0.1.10/32 => 10.0.1.10 2

原文中命令有误,是无法执行的,这里先暂时使用第一种方法,后续会补充上。

从这些流表下发方法中也可以认识到以下几点:

a)没有控制面下发的流表,仅数据面无法工作。

b)控制面下发的流表必须与P4程序中定义的table相吻合,从匹配字段(match-field)到动作(action).

c)P4定义的数据面所对应的控制面,可以是控制器、运行时CLI,也可以是SAI等。

2017/1/15

P4语言编程快速开始 实践一的更多相关文章

  1. P4语言编程快速开始 实践二

    参考:P4语言编程快速开始 上一篇系列博客:P4语言编程快速开始 实践二 Demo 2 本Demo所做的修改及实现的功能: 为simple_router添加一个计数器(counter),该计数器附加( ...

  2. Linux C语言编程基本原理与实践

    Linux C语言编程基本原理与实践(2018-06-16 19:12:15) Linux C语言编程基本原理与实践 高效的学习带着目的性: 是什么 -> 干什么 -> 怎么用 重识C语言 ...

  3. P4语言编程详解

    1.源码目录结构 P4项目源码可以在github上直接获取(https://github.com/p4lang).P4项目由很多个单独的模块组成,每个模块就是一个子项目,下面分别简单介绍一下各模块的功 ...

  4. p4语言编程环境安装

    p4语言主要是用来模拟交换机的交互,是新一代的SDN解决方案,可以让数据转发平面也具有可编程能力,让软件能够真正定义网络和网络设备.详细介绍 主要流程是:安装vmware.安装Ubuntu.下载Git ...

  5. 精通UNIX下C语言编程与项目实践

    cc  -I  //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编 ...

  6. Python编程快速上手--实践项目11.11.1

    from selenium import webdriver from selenium.webdriver.common.keys import Keys import time def messa ...

  7. 第二章 C语言编程实践

    上章回顾 宏定义特点和注意细节 条件编译特点和主要用处 文件包含的路径查询规则 C语言扩展宏定义的用法 第二章 第二章 C语言编程实践 C语言编程实践 预习检查 异或的运算符是什么 宏定义最主要的特点 ...

  8. R语言编程艺术(1)快速入门

    这本书与手上其他的R语言参考书不同,主要从编程角度阐释R语言,而不是从统计角度.因为之前并没有深刻考虑这些,因此写出的代码往往是一条条命令的集合,并不像是“程序”,因此,希望通过学习这本书,能提高编程 ...

  9. 华为C语言编程规范

    DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...

随机推荐

  1. Lucene入门教程

    Lucene教程 1 lucene简介 1.1 什么是lucene     Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么 ...

  2. MySql数据库基本介绍和基本语法

    一.数据库简单介绍 1. 按照数据库的发展时间顺序,主要出现了以下类型数据库系统: Ø 网状型数据库 Ø 层次型数据库 Ø 关系型数据库 Ø 面向对象数据库 上面4中数据库系统中,关系型数据库使用最为 ...

  3. STM32F4xx FPU的设置

    原文:http://blog.csdn.net/dlutxie/article/details/7980389 浮点运算一直是定点CPU的难题,比如一个简单的1.1+1.1,定点CPU必须要按照IEE ...

  4. MyEclipse8.5安装findbugs方法

    step 1:首先从官网下载findbugs插件: edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821.zipstep 2:将解压之后的edu.umd. ...

  5. Angularjs循环二维数组

    <div ng-app> <div ng-controller="test"> <div ng-repeat="links in slide ...

  6. 浅谈:html5和html的区别

    什么是html5呢? html5最先由WHATWG(Web 超文本应用技术工作组)命名的一种超文本标记语言,随后和W3C的xhtml2.0(标准)相结合,产生现在最新一代的超文本标记语言.可以简单点理 ...

  7. 彻底搞明白find命令的-mtime参数的含义【转载】

    转自: 彻底搞明白find命令的-mtime参数的含义-goolen-ITPUB博客http://blog.itpub.net/23249684/viewspace-1156932/ 以前一直没有弄明 ...

  8. Struts2, jquery, select二级联动

    1. 下载jquery.js文件放在webroot下js文件夹里 2. 配置struts.xml: <package name="default" namespace=&qu ...

  9. 正则抓取网页所有href和src

    根据抓取的页面,用正则来匹配页面href和src string UserAgent = "Mozilla/5.0 (Windows NT 5.2; rv:29.0) Gecko/201001 ...

  10. Dice Possibility

    Dice Possibility 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 What is possibility of rolling N dice and th ...