参考: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. Loadrunner之文件的下载(八)

    老猪提供: https://mp.weixin.qq.com/s?__biz=MzIwOTMzNDEwNw==&mid=100000013&idx=1&sn=624f5bc74 ...

  2. PullToRefreshListView上拉加载、下拉刷新 eclipse项目

    说明:此项目实在fragment中的,需要依赖library完成,还用到了Xuitls.jar包.使用了Pull解析XML eclipse中的项目: //注意:此刷新功能是使用的第三方的PullToR ...

  3. [转]SSL协议与数字证书原理

    1 SSL(Secure Socket Lclientyer)是netscclientpe公司设计的主要用于weserver的安全传输协议.这种协议在WESERVER上获得了广泛的应用. SSL在TC ...

  4. hdu1501 Zipper

    Zipper Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  5. ffmpeg合并多个视频

    实例1: 把4个视频(1.f4v, 2.f4v, 3.f4v, 4.f4v)合并成一个文件(out.mp4) 基本无损,而且速度飞快! #-vcodec copy -acodec copy   == ...

  6. CodeForces 525D Arthur and Walls

    广搜.看了官方题解才会的..... 定义2*2的小矩阵,有三个是点,一个是星,这样的小矩阵被称为元素块. 首先把所有元素块压入队列,每次取出对头,检查是否还是元素块,如果是 那么将那个*改为点,否则跳 ...

  7. Unity中www的基本应用

    Unity的www主要支持HTTP中的GET和POST方式,GET方式会将请求附加到URL后,POST方式则是通过FORM的形式提交. 以下为Unity客户端的信息: using UnityEngin ...

  8. Chapter 1 First Sight——24

    He looked away quickly, more quickly than I could, though in a flush of embarrassment I dropped my e ...

  9. MaterialDrawer的使用

    这是一个MaterialDesign风格的侧滑,在github上下载压缩包,按照github上的方式引入依赖,然后打开压缩包里面的例子程序,对照着APK看,即可知道怎么实现的(好像说了一堆废话..)

  10. jQuery常用及基础知识总结(一)

    Attribute: $(”p”).addClass(css中定义的样式类型); 给某个元素添加样式$(”img”).attr({src:”test.jpg”,alt:”test Image”}); ...