![]() |
失恋的充电器 · URL地址中的中文乱码怎么解决?_ITPUB博客· 1 年前 · |
![]() |
另类的单车 · jsp背景图片显示不出来-掘金· 1 年前 · |
![]() |
发怒的洋葱 · js去掉数字前面的0-掘金· 1 年前 · |
![]() |
善良的稀饭 · webview设置不弹出权限请求弹窗 - ...· 1 年前 · |
http://www.cnblogs.com/hanyan225/archive/2010/10/01/1839906.html
http://www.west263.com/info/html/wangzhanyunying/jianzhanjingyan/20080417/70218.html
http://www.cnblogs.com/lidp/archive/2009/12/02/1697479.html
GNU Binutils:
http://en.wikipedia.org/wiki/GNU_Binutils
Linux静态链接(库)、动态链接(库)、可执行文件加载相关问题(创建、选项、环境变量等)
(1) 概念// File: test1.cpp
#include <stdio.h>
void foo()
printf("This is foo in test1\n");
// File: test1.h
#ifndef TEST1_H
#define TEST1_H
void foo();
#endif
// File: test2.cpp
#include <stdio.h>
void foo()
printf("This is foo in test2\n");
// File: test2.h
#ifndef TEST2_H
#define TEST2_H
void foo();
#endif
1. 静态链接.a:
首先,先编译得到中间文件.o:
test1.cpp test1.h test2.cpp test2.h
#gcc -c test1.cpp -o test1.o
#gcc -c test2.cpp -o test2.o
test1.cpp test1.h test1.o test2.cpp test2.h test2.o
#
然后,利用ar命令打包得到.a文件:
#ar crv libtest1.a test1.o
a - test1.o
libtest1.a test1.cpp test1.h test1.o test2.cpp test2.h test2.o
(libtest2.a可以同理得到,说明:这里是由一个.o得到一个.a的情况)
命令:
说明:对于需要将多个.o打包成一个.a的情况,可以直接在后面列举所有的.o文件即可。另外,ar命令有很多选项,对于.a已经存在,往其中插入模块(.o),如何处理已经存在的.o等等其它的处理情况,这里不详细讨论。一般的使用是crv选项,c表示不管.a是否已经存在创建新的.a文件,r表示在库中插入模块(替换)。当插入的模块名已在库中存在,则替换同名的模块。假如若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,能够使用其他任选项来改变增加的位置。v表示显示详细操作信息。具体ar的使用参考:http://www.west263.com/info/html/wangzhanyunying/jianzhanjingyan/20080417/70218.html
关于nm命令,用来列出目标文档的符号清单,不仅仅适用于.a,也用于.so等。也不更多说明,一般常用的就是nm file或者nm -o file(信息会更详细),如下:
#ar crv libtest1.a test1.o
a - test1.o
#ar crv libtest2.a test2.o
a - test2.o
#ar crv libtest12.a test1.o test2.o
a - test1.o
a - test2.o
#nm libtest1.a
test1.o:
0000000000000000 T _Z3foov
U puts
#nm libtest2.a
test2.o:
0000000000000000 T _Z3foov
U puts
#nm libtest12.a
test1.o:
0000000000000000 T _Z3foov
U puts
test2.o:
0000000000000000 T _Z3foov
U puts
2. 动态链接得到.so:
首先,使用gcc的-fPIC选项编译得到PIC(位置无关代码)的中间文件。
然后,使用gcc的-shared选项对.o文件进行链接。
#gcc -c -fPIC test1.cpp -o test1.o
#gcc -c -fPIC test2.cpp -o test2.o
#gcc -shared test1.o -o libtest1.so
#gcc -shared test2.o -o libtest2.so
#gcc -shared test1.o test2.o -o libtest12.so
test2.o: In function `foo()':
test2.cpp:(.text+0x0): multiple definition of `foo()'
test1.o:test1.cpp:(.text+0x0): first defined here
collect2: ld 返回 1
#
(从这里也可以看到,gcc生成动态链接库会检查是否有重复定义的情况,上面的静态打包ar命令就不会检查。)
说明:必须使用-fPIC选项编译,否则使用-shared生成动态链接库的时候会出现链接错误。当然,上面是编译和链接分开的,也是可以一起完成,就不需要-c选项了,如gcc -fPIC -shared test.c -o libtest.so等。
关于nm在查看.so时候常见的使用方式:
上面有关于nm用于查看.a文件的说明,对于.so,通常使用下面的选项查看:
(参考:http://blog.sina.com.cn/s/blog_5dc87df60100bike.html
http://www.cppblog.com/noflybird/archive/2010/05/06/114618.aspx
http://apps.hi.baidu.com/share/detail/20625788)
-C:用C/C++的方式显示函数名(函数名在编译后会稍微改变一下,demangle和mangle)。
-g:仅显示外部符号。
我一般使用如下来查看动态链接库里面定义的函数(也可以用这个查看.a更好):
nm -C -g libtest1.so -A
或者进一步用T过滤结果:
nm -C -g libtest1.so -A | grep T
如下:
#nm -C -g libtest1.so -A | grep T
libtest1.so:000000000000057c T foo()
libtest1.so:00000000000005cc T _fini
libtest1.so:0000000000000460 T _init
1. 生成静态链接库的方式:先gcc编译得到.o文件,使用ar命令打包.o文件即可(ar crv xxx.a xxx.o xxx1.o xxx2.o...)。
2. 生成动态链接库的方式:用gcc -fPIC编译得到.o文件,然后用-shared选项进行链接即可。
3. 查看静态链接库和动态链接库的符号文件:nm,也可以查看其它文件的符号文件。比如:nm -C -g libtest1.so/libtest1.a -A | grep T的形式。
4. 经过上面的折腾,得到了如下的文件(下面会用到):
libtest12.a libtest1.a libtest1.so libtest2.a libtest2.so test1.h test2.h
(4) 静态链接库和动态链接库的“原始”使用
测试程序:
// File: main.cpp
#include "test1.h"
int main()
foo();
return 0;
}
1、和静态库链接:
直接参与链接即可:
libtest12.a libtest1.a libtest2.a main.cpp test1.h test2.h
#gcc main.cpp libtest1.a
#./a.out
This is foo in test1
#
当然,也可以把编译和链接分开,那么就先gcc -c main.cpp -o main.o得到main.o,然后gcc main.o libtest1.a即可。
这是最简单的和静态库链接的方式,直接作为gcc的输入参数(输入文件)参与链接。更复杂的情况是,要链接的库不在当前目录下,那么当然,需要指定文件的路径(相对路径或绝对路径)如下:
lib main.cpp test1.h test2.h
#gcc main.cpp ./lib/libtest1.a
#./a.out
This is foo in test1
2、和动态库链接:
直接参与链接即可,和静态链接库一样,gcc xxx.cpp xxx.so libs/abc/xxx.so.....,将要链接的库作为输入文件参数传递给gcc即可。
lib main.cpp test1.h test2.h
#gcc main.cpp lib/libtest1.so
#./a.out
This is foo in test1
总结:上面这是最“原始"的方式连链接静态库和动态库,即把库文件作为gcc的输入文件,规则当然和源文件和目标文件类似了,不管是使用相对路径还是绝对路径,总之是必须能让gcc直接找到的。对于这种方式,使用-L或者把libtest1.so复制到/lib、/usr/lib这些方式,都不能简化为"gcc main.cpp libtest1.so”(当然是libtest1.so不在当前目录的情况下)。说明:这一点是很基础的,但是时间久了反而犯迷糊了,以为-L也能对这种最原始的情况起到作用(gcc main.cpp libtest1.so -L./lib,其中libtest1.so在lib文件夹中)。
(5) 使用-l和-L链接静态库(-static)和动态库
上面的最原始的方式链接到动态库的方式有一个缺点在于:需要指定要链接的库的相对或绝对路径。那么,一个情况是,如果我们的程序需要链接到一些库,比如linux提供了很多库如pthread库等,如果需要链接到它们,当然,使用完整的路径是可以的。如下:
#gcc /lib64/libpthread.so.0 main.cpp lib/libtest1.so
#
这样的缺点是很明显的。为了改进,gcc提供了-l的方式来简化这个问题,在gcc选项中使用-lxxxx指定要链接的库的库名,对应的库名为libxxx.so或libxxx.so,同时,这个库是存在于“系统库目录”中。对于Linux而言,系统库目录默认为/lib和/usr/lib(或者/lib64和/usr/lib64,这里不讨论关于32和64位的问题)。另外,-L选项则用于将一个指定的目录加入到”系统库“的范畴,其实就是加入到链接器对库的搜索路径了。
所以,对于上面的例子,可以:
A、把libtest1.so复制到/lib中或者/usr/lib中,就可以直接使用:gcc -ltest1 main.cpp编译了。
B、如果libtest1.so不在搜索路径(/lib和/usr/lib中),那么编译会得到类似于:/usr/bin/ld: cannot find -ltest1的错误。可以使用-L将指定的目录加入到搜索路径,如:
lib main.cpp test1.h test2.h
#gcc -ltest1 main.cpp -Llib
#gcc -ltest1 main.cpp -L./lib
至于静态库,其规则和上面的一样,同样有"系统库目录"和-l的简写以及-L添加搜索路径。但是,默认情况下,gcc是进行动态链接的。如果需要使用静态链接,需要使用-static选项,使用了-static选项后,所有的-l指定的库都会去搜索路径中查找对应的.a静态库。而且,需要注意的是,-static也会改变gcc的默认链接的库的链接方式,也会链接静态库(关于gcc默认链接的库,比如libc等,默认都是动态库的,使用了-static后,会链接到libc.a静态库,关于哪些库是gcc的默认链接库下面会介绍)。
(6) gcc的-include和-I参数
这个内容本来和这里的内容无关,但是一般总是和-L一起讨论,所以就这里说明一下。-include用于包含头文件,功能和#include一样,一般很少用,一般都是在代码里用#include了。-I用于指定额外的“系统头文件”的搜索路径,对应于-L选项类似的功能。
对于使用<>的#include,头文件会去系统头文件(/usr/include)搜索,如果某些头文件不在系统头文件路径中,就需要使用-I指定了。
PS:-I和-L都可以在一个命令行下指定多个,增加多个路径,如gcc -lxxx foo.cpp -Llib1/ -Llib2/ -Llib3/等。
(7) 可执行文件的加载和运行和ldd命令
上面的内容都是关于如何编译和链接的问题,得到可执行文件,事实上,上面的例子中,有些可执行文件是不能执行的。
对于链接静态库的程序,由于静态链接会将代码直接拷贝到可执行文件中,链接后的可执行文件是可以不依赖于静态库.a直接运行的,所以问题主要是关于使用了动态库的程序的运行问题。对于使用动态库的程序,在程序加载过程中,有一个重要的一步是动态库的加载(有时候也说成动态库的动态链接),loader为/lib/ld-linux.so(参考http://blog.csdn.net/gengshenghong/article/details/7096511的(3)理解)。
动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;//只需在在该文件中追加一行库所在的完整路径如"/root/test/conf/lib"即可,然后ldconfig是修改生效。
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib。
先看下面的例子,说明一个问题:
#tree
├── lib
│ ├── libtest1.so
│ └── libtest2.so
├── libtest1.so
├── libtest2.so
├── main.cpp
├── test1.h
└── test2.h
1 directory, 7 files
#gcc main.cpp libtest1.so
#./a.out
./a.out: error while loading shared libraries: libtest1.so: cannot open shared object file: No such file or directory
#gcc main.cpp ./libtest1.so
#./a.out
This is foo in test1
#gcc main.cpp lib/libtest1.so
#./a.out
This is foo in test1
#gcc main.cpp /home/sgeng2/labs_temp/temp/libtest1.so
#./a.out
This is foo in test1
这里,使用gcc main.cpp libtest1.so编译成功了,居然运行说找不到共享库,使用./就可以了。当然,对于上面的任意一种情况,链接后删除了.so肯定也是运行不了的。那么,如果是下面的情况呢:
lib libtest1.so libtest2.so main.cpp test1.h test2.h
#gcc main.cpp ./libtest1.so
#./a.out
This is foo in test1
#../temp/a.out
This is foo in test1
#cd ..
#temp/a.out
temp/a.out: error while loading shared libraries: ./libtest1.so: cannot open shared object file: No such file or directory
#
会发现,使用gcc mai.cpp ./libtest1.so编译后,运行时,这个"./libtest1.so“的信息是保存了的,所以,只能在当前目录运行a.out,如果cd切换到其它目录,那么它仍然是去寻找./libtest1.so,自然就找不到了。那么,如果这里使用的是lib/libtest1.so链接,也是一样的,运行的时候,当前工作目录下需要有一个lib/libtest1.so的文件,如果使用的是绝对路径,那么当然,只要.so没有删除,都是可以运行的。可见,这种最“原始"的链接方式,它还是很傻的,局限性比较大。
总结:这种使用"原始"的方式来链接得到可执行文件,.so的路径信息是保存在可执行文件中的,在加载的时候需要查找对应的.so是否存在。上面的提到了"动态库的搜索路径的搜索顺序",这是用于使用-l和-L来链接的动态链接库的情况,对于这里的"原始"的方式并无改变,比如使用gcc main.cpp ./libtest1.so编译后,哪怕将libtest1.so复制到了/usr/lib中也没用。(个人理解,这种原始的指定路径的编译方式,应该属于"编译目标代码时指定的动态库搜索路径”,当然,一般说到这个编译目标代码时指定的动态库搜索路径,是指另外一个选项,下一部分说明)。
ldd命令:ldd命令用于显示一个可执行文件中依赖的所有.so在当前系统中的位置,简单理解,就是它会模拟可执行文件的加载,输出各个.so文件的路径,比如上面的所有路径的顺序,在不同的路径中放入.so,ldd得到的路径会显示实际loader查找到的路径。如果找不到.so或者.so有问题,ldd也会报错。
(8) 编译目标代码时指定的动态库搜索路径"-Wl,-rpath,"
gcc提供了-Wl,-rpath,xxx来指定程序运行时候搜索动态库的路径,和-L没有任何关系,-Wl,-rpath是在编译时指定,但是其用于运行时的loader,所以是一个比较特殊的选项,容易和-L混淆。说明:-Wl,-rpath,xxx指定的路径,如果使用的是相对路径,那么运行的时候,也是根据相对路径来查找.so,所以其实和上面说的"原始"方式进行链接,应该本质上是一回事。
这个选项可以指定多个路径,用":"分开即可。如:gcc -Wl,-rpath,path1:path2:path3 main.cpp -ltest -Llib/等。
1. 对于静态库,可以使用"原始"方式(指定路径作为gcc输入参数)链接静态库,也可以使用-l&&-L的方式,但是,需要使用-static选项。另外,默认的gcc链接方式是动态的,所以使用了-static,会让gcc默认链接的库也链接静态版本。
2. 对于使用"原始"方式(指定路径作为gcc输入参数)链接动态库的情况,运行时候限制太多,必须是怎么编译链接的,就要保证运行时候按照当时的路径能找到动态链接库,当然,这种方式很少用,一般都是用-l&&-L来链接动态链接库。
3. 对于使用-l来链接.so的情况,编译器会到/lib,/usr/lib和-L指定的路径下查找-l指定的.so文件来进行链接。搜索先后顺序为:-L指定的路径;/usr/lib;/lib。
4. 对于使用-l链接.so的情况,在运行的时候。会根据相应的路径搜索.so文件来进行加载运行,加载的时候,动态库的搜索路径搜索的先后顺序是:编译目标代码时指定的动态库搜索路径;环境变量LD_LIBRARY_PATH指定的动态库搜索路径;配置文件/etc/ld.so.conf中指定的动态库搜索路径;默认的动态库搜索路径/lib;默认的动态库搜索路径/usr/lib。
5. -Wl,-rpath用于编译目标代码时指定的动态库搜索路径,和-L没有关系,一个指定的路径用于运行时加载.so的搜索,一个指定的路径用于编译时链接.so中符号的搜索。
(9) 链接多个库的问题(多个库都有同一函数的定义)
比如:两个.a文件都定义了函数foo,然后都参与链接,实际使用的是哪一个?如果是两个.so呢?一个.a和一个.so呢?
(10) 补充:
1. 关于搜索路径
上面已经总结了相关的头文件和库文件的搜索路径问题,需要说明的是,实际的GCC的搜索路径还可能会和其他因素有关,比如一些环境变量的设置,还有gcc会将自己的安装目录下的lib文件夹或者include文件夹等等加入搜索路径,包括可以通过sysroot等选项改变默认的设置,具体参考http://blog.csdn.net/gengshenghong/article/details/7108634的总结。当然,为了更好的了解这些信息,gcc也提供了几个相关命令来查看相关信息。
gcc -print-search-dirs:打印安装、程序和库的搜索路径。输出示例如下:
#gcc --print-search-dirs
安装:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/
程序:=/usr/libexec/gcc/x86_64-redhat-linux/4.6.0/:/usr/libexec/gcc/x86_64-redhat-linux/4.6.0/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/:/usr/lib/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../x86_64-redhat-linux/bin/x86_64-redhat-linux/4.6.0/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../x86_64-redhat-linux/bin/
库:=/usr/lib/gcc/x86_64-redhat-linux/4.6.0/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../x86_64-redhat-linux/lib/x86_64-redhat-linux/4.6.0/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../x86_64-redhat-linux/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../x86_64-redhat-linux/4.6.0/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/:/lib/x86_64-redhat-linux/4.6.0/:/lib/../lib64/:/usr/lib/x86_64-redhat-linux/4.6.0/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../x86_64-redhat-linux/lib/:/usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../:/lib/:/usr/lib/
#
gcc -v file.c:显示编译file.c时候的详细信息(其中会显示一些搜索头文件的顺序的信息和LIBRARY_PATH、COMPILER_PATH等等。也可以直接gcc -v,显示的就是gcc的基本配置信息。
gcc -dumpspecs:显示所有内建 spec 字符串。
gcc -dM -E file.c:显示预处理file.c中所有的宏定义。
总之,gcc搜索路径还是有些复杂的,不需要所有细节全部记清楚,但是至少要知道会有哪些内容需要被考虑。
2. GCC的--sysroot选项
这个选项一般用于交叉编译,用于指定编译所需要的头文件,及链接库(的root目录)等。
3. GCC环境变量和配置选项等
http://www.linuxsir.org/bbs/thread304996.html
http://blog.csdn.net/yangruibao/article/details/6869323
http://jimobit.blog.163.com/blog/static/28325778200991524826935/
第1 章Linux操作系统概述................... .......................................................................... 2
1.1 Linux发展历史........................................................ 2
1.1.1 Linux的诞生和发展.............................................. 2
1.1.2 Linux名称的由来........................................ ........ 3
1.2 Linux的发展要素...................................................... 3
1.2.1 U N I X操作系统.................................................. 4
1.2.2 Minix操作系统.................................................. 4
1.2.3 POSIX 标准.....................................................4
1.3 Linux 与 U N I X 的异同.................................................. 5
1 . 4 操作系统类型选择和内核版本的选择..................................... 5
1.4.1常见的不同公司发行的Linux异同................................. 6
1.4.2 内核版木的选择..................................................6
1.5 Linux的系统架构...................................................... 7
1.5.1 Linux内核的主要模块............................................ 7
1.5.2 Linux的文件结构................................................ 9
1.6 G N U 通用公共许可证..................................................10
1.6.1 G P L许可证的历史.............................................. 10
1.6.2 G P L 的白由理念................................................ 10
1.6.3 G P L 的基本条款................................................ 11
1.6.4关于G P L 许町证的争议......................................... 12
1.7 Linux软件开发的可借鉴之处........................:.................. 12
1-8 .................................................................13
第2 章Linux编程环境....................................................................................................14
2.1 Linux环境下的编辑器................................................. 14
2.1.1 v i m使用简介...................................................14
2 . 1 . 2使用v i m建立文件.............................................. 15
2 . 1 . 3使用v i m编辑文本.............................................. 16
2.1.4 v i m的格式设置.................................................18
2.1.5 vim 配置文件....................................................................................................... ..
2 . 1 . 6 使用其他编辑器...................................................................................................
2.2 Linux下的G C C 编译器工具集.......................................... 19
2.2.1 G C C 简介......................................................19
2 . 2 . 2 编译程序的基本知识......................................................................................... 21
2.2.3 .单个文件编译成执行文件........................................ 22
2 . 2 . 4编译生成目标文件.............................................. 22
2 . 2 . 5多文件编译............ ........................................ 23
2.2.6 预处理........................................................ 24
2 . 2 . 7编译成汇编语言.................................................24
2 . 2 . 8生成和使用静态链接库.......................................... 25
2 . 2 . 9生成动态链接库.................................................26
2.2.10动态加载库................................................... 29
2.2.11 G C C 常用选项................................................ 31
2 . 2 . 1 2编译环境的搭建................................................33
2.3 Makefile 文件简介.....................................................34
2.3.1 一个多文件的工程例子............................. ............. 34
2 . 3 . 2多文件工程的编译.............................................. 36
2.3.3 Makefile 的规则.................................................37
2.3.4 Makefile 中使用变量............................................ 39
2 . 3 . 5搜索路径...................................................... 43
2 . 3 . 6自动推导规则.................................................. 44
2.3.7 递归 make......................................................44
2.3.8 Makefile 中的函数.............................................. 46
2 . 4 用G D B 调试程序..................................................... 47
2 . 4 . 1编译可调试程序.................................................48
2.4.2 使用G D B 调试程序............................................. 49
2.4.3 G D B 常用命令..................................................52
2.4.4 其他的 G D B ....................................................59
2.5 顿.................................................................60
第3 章文件系统简介........................................................ 61
3.1 Linux下的文件系统.................................................. 61
3.1.1 Linux下文件的内涵............................................. 61
3.1.2 文件系统的创建................................................. 62
3 . 1 . 3挂接文件系统.................................................. 64
3.1.4 索弓丨节点 inode.......... •'...................................... 65
3.1.5 普通文件...................................................... 66
3 . 1 . 6设备文件...................................................... 66
3 . 1 . 7虚拟文件系统V F S .............................................. 68
3.2 文件的通用操作方法................................................. 72
3 . 2 . 1文件描述符.................................................... 72
3 . 2 . 2打开创建文件open()、create()函数................................ 72
3 . 2 . 3关闭文件closeO函数............................................ 76
3 . 2 . 4读取文件read()函数............................................. 77
3.2.5 写文件write()函数.............................................. 79
3 . 2 . 6文件偏移lseekO函数............................................ 80
3 . 2 . 7获得文件状态fstat()函数.....................•'................... 83
3 . 2 . 8文件空间映射m m a p ()函数....................................... 85
3 . 2 . 9文件属性fcntl()函数............................................. 88
3. 2 . 1 0文件输入输出控制ioctl()函数....................................92
3.3 socket文件类型....................................................... 93
3.4 /J、@ .................................................................93
第4 章程序、进程和线程.................................................... 94
4 . 1 程序、进程和线程的概念.............................................. 94
4 . 1 . 1程序和进程的差别............................................ ’."94
4.1.2 Linux环境下的进程............................................. 95
4 . 1 . 3进程和线程.................................................... 96
4 . 2 进程产生的方式...................................................... 96
4.2.1 进程号........................................................ 96
4.2.2 进蟬复制 fork()................................................. 97
4.2.3 system()方式....................................................98
4.2.4 进程执行exec()函数系列......................................... 99
4 . 2 . 5所有用户态进程的产生进程init................................. 100
4 . 3 进程间通信和同步................................................... 101
4.3.1 半双工管道................................................... 101
4.3.2 命名管道..................................................... 107
4.3.3 消息队列..................................................... 108
4 . 3 . 4消息队列的一个例子........................................... 114
4.3.5 信号量......................... .............................. 116
4 . 3 . 6共享内存..................................................... 121
4.3.7 信号.......................................................... 124
4.4 Linux下的线程...................................................... 127
4 . 4 . 1多线程编程实例................................................127
4.4.2 Linux 下线程创建函数 pthread_create()............................ 129
4.4.3 线程的结束函数 pthread_join()和 pthread_exit().....................129
4.4.4 线程的属性................................................... 130
4 . 4 . 5线程间的互斥................................................. 132
4 . 4 . 6线程中使用信号量..............................................133
• VII •
4-5 純............................................................... 136
第2 篇Linux用户层网络编程
第5 章T C P / I P协议族简介.................................................. 138
5.1 O S I网络分层介绍....................................................138
5.1.1 O S I网络分层结构............................................. 138
5.1.2 O S I的7 层网络结构........................................... 139
5.1.3 O S I参考模塑中的数据传输..................................... 140
5.2 TCP/IP 协议找....................................................... 141
5.2.1 TCP/IP协议栈参考模型......................................... 141
5 . 2 . 2主机到网络层协议............................................. 143
5.2.3 IP 协议....................................................... 144
5.2.4 网际控制报文协议(ICMP) .................................... 146
5.2.5 传输控制协议(TCP) ......................................... 150
5 . 2 . 6用户数据报文协议(U D P ) ..................................... 154
5 . 2 . 7地址解析协议(A R P) ......................................... 156
5.3 IP地址分类与T C P / U D P端U .......................................... 158
5 . 3 . 1因特网中IP地址的分类........................................ 159
5.3.2 子网掩码(subnet mask address) ................................ 161
5.3.3 IP地址的配置................................................. 162
5.3.4 端口......................................................... 163
5 . 4 主机字节序和网络字节序............................................. 163
5 . 4 . 1字节序的含义................................................. 164
5 . 4 . 2网络字节序的转换............................................. 164
5.5 /J、@ ........................................................... .....166
第6 章应用层网络服务程序简介...................... ;..................... 167
6.1 H T T P协议和服务....................................................167
6.1.1 H T T P 协议概述.................................................167
6.1.2 H T T P协议的基本过程.......................................... 168
6.2 F T P协议和服务......................................................170
6.2.1 F T P协议概述..................................................170
6.2.2 F T P协议的工作模式........................................... 172
6.2.3 F T P协议的传输方式........................................... 172
6.2.4 —个简单的F T P过程........................................... 173
6.2.5 常用的F T P工具............................................... 173
6.3 T E L N E T协议和服务................................................. 174
6 . 3 . 1远程登录的基本概念........................................... 174
• VIII •
6 . 3 . 2使用T E L N E T协议进行远程登录的工作过程...................... 174
6.3.3 T E L N E T 协议................................................. 174
6.4 N F S 协议和服务......................................................176
6.4.1 安装N F S服务器和客户端...................................... 176
6 . 4 . 2服务器端的设定................................................176
6 . 4 . 3客户端的操作................................................. 177
6.4.4 showmount 命令................................................177
6 . 5 自定义网络服务..................................................... 177
6.5.1 xinetd/inetd....................................................178
6.5.2 xinetd月艮务配置................................................178
6 . 5 . 3自定义网络服务............................................... 179
6.6 小结................................................................180
第7 章T C P 网络编程基础...............................................181
7.1 套接字编程基础知识................................................. 181
7.1.1 套接字地址结构................................................181
7 . 1 . 2用户层和内核层交互过程....................................... 183
7.2 T C P 网络编程流程................................................... 184
7.2.1 T C P网络编程架构............................................. 184
7 . 2 . 2创建网络插口函数socket()...................................... 186
7.2.3 绑定一个地址端口对bind()......................................189
7.2.4 监听本地端口 listen............................................ 192
7.2.5 接受一个网络请求acceptO...................................... 194
7 . 2 . 6连接H 标网络服务器connect()................................... 199
7.2.7 写入数据函数writeO........................................... 200
7 . 2 . 8读取数据函数readO............................................ 201
7 . 2 . 9关闭套接字函数close()......................................... 201
7 . 3 服务器/客户端的简单例子............................................ 202
7.3.1 例子功能描述........................................... ......202
7 . 3 . 2服务器网络程序................................................203
7 . 3 . 3服务器读取和显示字符串....................................... 205
7 . 3 . 4客户端的网络程序............................................. 205
7 . 3 . 5客户端读取和显示字符串....................................... 206
7 . 3 . 6编译运行程序................................................. 206
7 . 4 截取信号的例子..................................................... 207
7.4.1 信号处理..................................................... 207
7.4.2 信号 SIGPIPE..................................................208
7.4.3 信号 SI G INT.................................... •.............. 208
7.5 /J、g ................................................................208
• IX •
第8 章服务器和客户端信息的获取...........................................210
8 . 1 字节序............................................................................................................................210
8 . 1 . 1 大端字节序和小端字节序...............................................................................210
8 . 1 . 2 字节序转换函数................................................................................................212
8.1.3 一个字节序转换的例子......................................... 214
8 . 2 字符串I P地址和二进制IP地址的转换................................. 217
8.2.1 inet_xxx()函数................................................. 217
8.2.2 inet_pton()和 inet_ntop()函数.....................................219
8 . 2 . 3使用8.2.1节地址转换函数的例子............................ .•••••••220
8.2.4 使用函数 inet_pton()和函数 inet—ntop()的例子......................223
8 . 3 套接字描述符判定函数issockettype()................................... 223
8 . 3 . 1进行文件描述符判定的函数issockettypeO.........................224
8.3.2 main()g| 数.................................................... 224
8.4 IP地址与域名之间的相互转换................................................................................. 225
8.4.1 D N S 原理.....................................................225
8 . 4 . 2获取主机信息的函数........................................... 226
8 . 4 . 3使用主机名获取主机信息的例子................................. 228
8 . 4 . 4函数gethostbyname()不可重入的例子............................. 230
8 . 5 协议名称处理函数................................................... 232
8.5.1 xxxprotoxxx()函数............................................. 232
8 . 5 . 2使用协议族函数的例子......................................... 233
8.6 小结................................................................236
第9 章数据的I O和复用....................................................237
9.1 IO 函数.......................................................................................................................... 237
9 . 1 . 1使用recv()函数接收数据........................................237
9 . 1 . 2 使用sendO函数发送数据................................................................................239
9 . 1 . 3 使用readvO函数接收数据..............................................................................240
9 . 1 . 4 使用writev()闲数发送数据.............................................................................240
9 . 1 . 5使用recvmsgO函数接收数据.................................... 242
9 . 1 . 6 使用sendmsgO函数发送数据.........................................................................244
9.1.7 I O函数的比较.................................................246
9.2 使用I O函数的例子.................................................. 246
9 . 2 . 1客户端处理框架的例子......................................... 246
9 . 2 . 2服务器端程序框架............................................. 248
9.2.3 使用 recv()和 send()函数........................................ 249
9.2.4 使用 readv()和 write()函数.......................................251
9.2.5 使用 recvmsgO和 sendmsg()函数..................................253
9.3 10 模型............................................................. 256
9 . 3 . 1阻塞I O模型.................................................. 256
• X •
9 . 3 . 2非阻塞1 0模型................................................ 257
9.3.3 10 复用....................................................... 257
9 . 3 . 4信号驱动I O模型.............................................. 258
9 . 3 . 5异步I O模型.................................................. 258
9.4 select()函数和 pselect()函数............................................ 259
9.4.1 select()闲数.................................................... 259
9.4.2 pselect()函数...................................................261
9.5 poll()函数和 ppoll()函数............................................... 262
9.5.1 poll()函数..................................................... 263
9.5.2 p p o l l O ® ^ .................................................... 264
9 . 6 非阻塞编程.......:.................................................. 264
9 . 6 . 1非阻塞方式程序设计介绍....................................... 264
9 . 6 . 2非阻塞程序设计的例子......................................... 264
9.7 小结................................................................266
第1 0章基于U D P 协议的接收和发送...................................... ,...267
10.1 U D P 编程框架......................................................267
10.1.1 U D P 编程框图................................................ 267
10.1.2 U D P 服务器编程框架.......................................... 269
10.1.3 U D P 客户端编程框架.......................................... 269
10.2 U D P 协议程序设计的常用函数....... :................................270
10.2.1建立套接字socket()和绑定套接字bind()......................... 270
10.2.2 接收数据 recvfrom()/recv()......................................270
10.2.3 发送数据 sendtoO/sendO...............................................................................275
10.3 U D P 接收和发送数据的例子.......................................... 279
10.3.1 U D P 服务器端................................................ 279
10.3.2 U D P 服务器端数据处理........................................280
10.3.3 U D P 客户端..................................................281
10.3.4 U D P 客户端数据处理.......................................... 281
10.3.5 测试 U D P 程序............................................... 282
10.4 U D P 协议程序设计中的几个问题......................................282
10.4.1 U D P 报文丢失数据............................................ 282
10.4.2 U D P 数据发送中的乱序........................................284
10.4.3 U D P 协议中的 connect()函数....................................287
10.4.4 U D P 缺乏流量控制............................................ 287
10.4.5 U D P 协议中的外出网络接口....................................289
10.4.6 U D P 协议中的数据报文截断....................................290
10.5 小结.............................................................. 291
第1 1章高级套接字........................................................ 292
11.1 U N I X 域函数.......................................................292
• XI •
11.1.1 UNIX域函数的地址结构..............................................................................292
1 1 .1 .2套接字函数.................................................................................................... 293
11 . 1 . 3 使用UNIX域函数进行套接字编程............................................................ 293
11.1.4传递文件描述符.............................................. 296
11.1.5 socketpair()闲数............................................................................................. 296
11.1.6传递文件描述符的例子.................................................................................297
11.2 广播............................................................................................................................. 302
11.2.1 广播的IP地址............................................................................................... 302
11.2.2广播与单播的比较......................................................................................... 303
11.2.3 广播的示例.....................................................................................................304
1 1 . 3多播................................................
11.3.1多播的概念.......................
1 1 .3 .2广域网的多播...................
11.3.3多播的编程.......................
11.3.4 内核中的多播...................
11.3.5 一个多播例子的服务器端
11.3.6 —个多播例子的客户端••••
1 1 . 4数据链路层访问...........................
11.4.1 SOCK_PACKET 类型……
11.4.2设置套接U 以捕获链路帧的编程方法............................ 320
11.4.3从套接口读取链路帧的编程方法................................ 321
11.4.4定位IP包头的编程方法....................................... 322
11.4.5定位T C P报头的编程方法..................................... 323
11.4.6定位U D P 报头的编程方法..................................... 325
11.4.7定位应用层报文数据的编程方法................................ 326
11.4.8使用S O C K _ P A C K E T编写A R P 请求程序的例子................. 326
11.5 329
第1 2章套接字选项........................................................330
12.1 获取和设置套接字选项 getsocketopt()/setsocketopt()......................330
12.1.1 getsockopt()函数和 setsocketopt()函数的介绍......................330
12.1.2套接字选项................................ ..................331
12.1.3套接字选项简单示例.......................................... 332
12.2 S O L ^ S O C K E T 协议族选项........................................... 336
12.2.1 S O—B R O A D C A S T 广播选项....................................336
12.2.2 S O—D E B U G 调试选项......................................... 337
12.2.3 S O _ D O N T R O U T E 不经过路由选项............................. 337
12.2.4 S O—E R R O R 错误选项......................................... 338
12.2.5 S O _ K E E P A L I V E 保持连接选项................................. 338
12.2.6 S O L I N G E R缓冲区处理方式选项...............................339
• XII •
12.2.7 S O _ O O B I N L I N E带外数据处理方式选项.........................342
12.2.8 S O _ R C V B U F 和 S O一S N D B U F 缓冲区大小选项................... 342
12.2.9 S O _ R C V L O W A T 和 S O _ S N D L O W A T 缓冲区下限选项............ 343
12.2.10 S O _ R C V T I M E O 和 S O _ S N D T I M E O 收发超时选项............... 343
12.2.11 S O _ R E U S E R A D D R 地址重用选项............................. 344
12.2.12 S O—E X C L U S I V E A D D R U S E 端 U 独占选项...................... 344
12.2.13 S 0 _ T Y P E套接字类型选项.................................... 345
12.2.14 SO_BSDCOMPAT 与 BSD 銮接字兼容选项............................................345
12.2.15 S O _ B I N D T O D E V I C E套接字网络接口绑定选项................. 345
12.2.16 S O _ P R I O R I T Y套接字优先级选项............................. 346
12.3 I P P R O T O J P 选项...................................................347
12.3.1 IP-HD RT NCL 选项............................................ 347
12.3.2 IP O P T N I O S 选项............................................ 347
12.3.3 IP_TOS 选项................................................. 347
12.3.4 IP_TTL 选项..................................................347
12.4 IPP RO TO_TCP 选项................................................. 348
12.4.1 T C P _ K E E P A L I V E 选项................... ..................... 348
12.4.2 T C P _ M A X R T 选项............................................ 348
12.4.3 T C P—M A X S E G 选项.......................................... 349
12.4.4 T C P _ N O D E L A Y 和 T C P _ C O R K 选项............................ 349
1 2 . 5使用套接字选项.................................................... 351
12.5.1设置和获取缓冲区大小........................................ 351
12.5.2获取套接字类型的例子........................................ 355
12.5.3使用套接字选项的综合例子.................................... 356
12.6 ioctl()函数.......................................................... 361
12.6.1 ioctl()函数的命令选项......................................... 361
12.6.2 ioctl()函数的 IO 请求.......................................... 363
12.6.3 ioctl()函数的文件请求......................................... 365
12.6.4 ioctl()函数的网络接U 请求:.....................................365
12.6.5使用ioctl()函数对A R P 高速缓存操作........................... 372
12.6.6使用ioct〖()函数发送路由表请求.................................374
12.7 fcntl()函数......................................................... 374
12.7.1 fcntl()函数的选项............................................. 375
12.7.2使用fcntl()函数修改套接字非阻塞属性.......................... 375
12.7.3使用fcntlO函数设置信号属主...................................376
12.8 小结...............................................................376
第13章原始套接字......................................................................................................377
13.1 概述...............................................................377
1 3 . 2原始套接字的创建.................................................. 379
• XIII •
13.2.1 S O C K J I A W 选项............................................. 379
13.2.2 IPJHDR 1NCL 套接字选项......................................379
13.2.3 不需要bindO函数............................................. 380
1 3 . 3原始套接字发送报文................................................ 380
13.4 原始套接字接收报文................................................ 380
1 3 . 5原始套接字报文处理时的结构........................................ 381
13.5.1 1 P头部的结构........................................... ..... 381
13.5.2 I C M P 头部结构............................................... 382
13.5.3 U D P 头部结构................................................ 384
13.5.4 T C P 头部结构................................................ 386
13.6 ping 的例子........................................................ 387
13.6.1 协议格式............................................. •••..... 388
13.6.2 校验和函数.................................................. 389
13.6.3 设置I C M P发送报文的头部.................................... 390
13.6.4剥离I C M P接受报文的头部.................................... 391
13.6.5 计算时间差.................................................. 392
13.6.6发送报文.................................................... 393
13.6.7接收报文.................................................... 394
13.6.8主函数过程.................................................. 395
13.6.9 主函数 main()................................................ 397
13.6.10 编译测试................... ................................ 400
1 3 . 7洪水攻击.......................................................... 400
13.8 I C M P洪水攻击..................................................... 401
13.8.1 I C M P洪水攻击的原理.........................................401
13.8.2 I C M P洪水攻击的例子.........................................401
13.9 U D P 洪水攻市......................................................405
13.10 S Y N 洪水攻击.....................................................409
13.10.1 S Y N 洪水攻击的原理.........................................409
13.10.2 S Y N 洪水攻击的例子.........................................409
13.11 小结............................................................. 413
第1 4章服务器模型选择....................................................414
1 4 . 1循环服务器:........................................................ 414
14.1.1 U D P 循环服务器.............................................. 414
14.1.2 T C P循环服务器.............................................. 417
1 4 . 2简单并发服务器.................................................... 420
14.2.1并发服务器的模型............................................ 420
14.2.2 U D P 并发服务器.............................................. 420
14.2.3 T C P并发服务器.............................................. 423
14.3 T C P的高级并发服务器模型.......................................... 426
. XIV •
14.3.1 单客户端单进程,统一 accept()................................. 426
14.3.2 单客户端单线程,统一accept()................................. 429
1 4.3.3单客户端单线程,各线程独自acceptO,使用互斥锁.............. 431
14.4 I O复用循环服务器..................................................435
14.4.1 I O复用循环服务器模型介绍....................................435
14.4.2 I O复用循环服务器模型的例子..................................436
14.5 440
第1 5章IPv6简介.......................... ...............................441
15.1 IPv4 的缺陷........................................................ 441
15.2 IPv6 的特点........................................................ 442
15.3 IPv6 的地址......................:.................................. 443
15.3.1 IPv6的单播地址.............................................. 443
15.3.2可聚集全球单播地址.......................................... 443
15.3.3 本地使用单播地址............................................ 444
15.3.4 兼容性地址.................................................. 445
15.3.5 IPv6 多播地址................................................ 446
15.3.6 IPv6 任播地址................................................ 446
15.3.7主机的多个IPv6地址......................................... 447
15.4 IPv6 的头部........................................................ 447
15.4.1 IPv6 头部格式........................................ ........ 447
15.4.2 与IPv4头部的对比........................................... 448
15.4.3 IPv6 的 T C P 头部............................................. 449
15.4.4 IPv6 的 U D P 头部............................................. 449
15.4.5 IPv6 的 I C M P 头部............................................ 449
15.5 IPv6运行环境...................................................... 451
15.5.1 加载 IPv6 模块............................................... 451
15.5.2查看是否支持IPv6............................................ 452
15.6 IPv6的结构定义.................................................... 453
15.6.1 IPv6的地址族和协议族........................................453
15.6.2套接字地址结构...............................................453
15.6.3 地址兼容考虑................................................ 455
15.6.4 IPv6 通用地址................................................ 455
15.7 IPv6的套接字函数.................................................. 456
15.7.1 socketO 函数.................................................. 456
15.7.2没有发生改变的函数.......................................... 456
15.7.3 发生改变的函数...............................................457
15.8 IPv6的套接字选项.................................................. 457
15.8.1 IPv6的套接字选项............................................ 457
15.8.2 单播跳限 I P V 6 _ U N I C A S T _ H O P S............................... 459
• XV •
15.8.3发送和接收多播包............................................ 459
15.8.4 IPv6中获得时间戳的ioctl命令................................. 460
15.9 IPv6的库函数...................................................... 460
15.9.1地址转换函数的差异.......................................... 460
15.9.2域名解析函数的差异.......................................... 461
15.9.3 测试宏...................................................... 463
15.10 IPv6的编程的一个简单例子......................................... 463
15.10.1 服务器程序................................................. 464
15.10.2 客户端程序................................................. 465
15.10.3 编译调试................................................... 467
15.11 小结............................................................. 467
第3 篇Linux内核网络编程
第16章Linux内核中网络部分结构以及分布...............................................................470
16.1 概述...............................................................470
16.1.1代码目录分布................................................ 470
16.1.2内核中网络部分流程简介...................................... 472
16.1.3系统提供修改网络流程点...................................... 474
16.1.4 sk_buff 结构..................................................475
16.1.5 网络协议数据结构inet_protosw................................. 478
1 6 . 2软中断C P U 报文队列及其处理....................................... 479
16.2.1 Linux内核网络协议层的层间传递手段— 软中断................ 479
1 6 . 2 . 2网络收发处理软中断的实现机制................................ 481
16.3 socket数据如何在内核中接收和发送...................................482
16.3.1 socket()的初始化.............................................. 482
16.3.2 接收网络数据recv()........................................... 482
16.3.3发送网络数据sendO........................................... 483
16.4 小结...............................................................484
第17章neffilter框架内报文处理.................................................................................485
17.1 netfilter............................................................ 485
17.1.1 netfilter 简介..................................................485
17.1.2 netfilter 框架..................................................486
17.1.3 netfilter 检査时的表格.........;................................487
17.1.4 netfilter 的规则................................................487
17.2 iptables 和 netfilter...................................................488
17.2.1 iptables 简介..................................................488
17.2.2 iptables 的表和链............................................. 488
• XVI •
17.2.3 使用iptables设置过滤规则.....................................489
1 7 . 3内核模块编程...................................................... 492
17.3.1 内核 “Hello, World! ”程序................................... 492
17 . 3 . 2内核模块的基本架构.......................................... 494
1 7 . 3 . 3内核模块加载和卸载过程...................................... 496
1 7 . 3 . 4内核模块初始化和清理函数.................................... 497
1 7 . 3 . 5内核模块初始化和淸理过程的容错处理.......................... 497
1 7 . 3 . 6内核模块编译所需的Makefile.................................. 498
17.4 5 个钩子点......................................................... 499
17.4.1 netfilter 的 5 个钩子,点......................................... 499
17.4.2 N F H O O K 'k .................................................500
17.4.3钩了.的处理规则.............................................. 501
1 7 . 5注册/注销钩子...................................................... 502
17.5.1 结构 nf_hook_ops............................................. 502
17.5.2注册钩子.................................................... 503
17.5.3 注销钩子.................................................... 504
17.5.4注册注销函数................................................ 504
1 7 . 6钩子的简单处理例子................................................ 505
17.6.1 功能描述.................................................... 505
17.6.2 需求分析.................................................... 506
17.6.3 ping回显屏蔽实现............................................ 506
17.6.4禁止向目的IP地址发送数据的实现............................. 506
17.6.5 端口关闭实现................................................ 506
17.6.6动态配置实现................................................ 508
17.6.7可加载内核实现代码.......................................... 509
17.6.8应用层测试代码实现.......................................... 516
17.6.9 编泽运行.................................................... 516
17.7 •点多个钩子的优先级...............................................517
1 7 . 8校验和问题........................................................ 518
17.9 小结.... ...........................................................518
第4篇综合案例
第1 8章一个简单W e b 服务器的例子S H T T P D ............................... 522
18.1 S H T T P D的需求分析................................................ 522
18.1.1 S H T T P D启动参数可动态配置的需求............................ 523
18.1.2 S H T T P D的多客户端支持的需求................................ 524
18.1.3 S H T T P D支持方法的需求...................................... 525
18.1.4 S H T T P D支持的H T T P协议版本的需求.......................... 526
• XVII •
18.1.5 S H T T P D支持头部的需求...................................... 527
18.1.6 S H T T P D 定位 URI 的需求......................................527
18.1.7 S H T T P D 支持 CGI 的需求......................................528
18.1.8 S H T T P D错误代码的需求............... ....................... 529
18.2 S H T T P D的模块分析和设计.......................................... 530
18.2.1 S H T T P D 的主函数............................................ 530
18.2.2 S H T T P D命令行解析的分析设计................................ 531
18.2.3 S H T T P D配置文件解析的分析设计.............................. 532
18.2.4 S H T T P D的多客户端支持的分析设计............................ 534
18.2.5 S H T T P D头部解析的分析设计.................................. 536
18.2.6 S H T T P D 对 URI 的分析设计....................................537
18.2.7 S H T T P D支持方法的分析设计.................................. 537
18.2.8 S H T T P D支持C G I的分析设计................................. 538
18.2.9 S H T T P D错误处理的分析设计................................. <540
18.3 S H T T P D各模块的实现.................................... :......... 542
18.3.1 S H T T P D命令行解析的实现.................................... 543
18.3.2 S H T T P D文件配置解析的实现.................................. 545
18.3.3 S H T T P D的多客户端支持的实现................................ 547
18.3.4 S H T T P D所请求U R I解析的实现............................... 551
18.3.5 S H T T P D方法解析的实现...................................... 552
18.3.6 S H T T P D响应方法的实现...................................... 552
18.3.7 S H T T P D 支持 CGI 的实现......................................556
18.3.8 S H T T P D支持H T T P协议版本的实现............................ 559
18.3.9 S H T T P D内容类型的实现...................................... 559
18.3.10 S H T T P D错误处理的实现..................................... 561
18.3.11 S H T T P D生成目录下文件列表文件的实现.......................563
18.3.12 S H T T P D主函数的实现....................................... 565
18.4 S H T T P D的编译、调试和测试........................................ 566
18.4.1 建立源文件...................................................566
18.4.2 制作 Makefile.................................................566
18.4.3 制作执行文件........................................:....... 567
18.4.4使用不同的浏览器测试服务器程序.............................. 567
18.5 小结...............................................................568
第1 9章一个简单网络协议栈的例子S I P ......................................569
19.1 S I P网络协议找的功能描述........................................... 569
19.1.1 SIP网络协议栈的基本功能描述................................ 570
19.1.2 S I P网络协议栈的分层功能描述................................ 570
19.1.3 S I P网络协议栈的用户接U 功能描述............................ 571
19.2 S I P网络协议找的架构............................................... 571
• XVIII •
19.3 S I P网络协议找的存储区缓存......................................... 572
19.3.1 SIP存储缓冲的结构定义....................................... 573
19.3.2 SIP存储缓冲的处理函数....................................... 577
19.4 S I P网络协议找的网络接U 层......................................... 579
19.4.1 SI P网络接U 层的架构......................................... 579
19.4.2 S I P网络接U 层的数据结构...................................•.••■580
19.4.3 S I P网络接口层的初始化函数...................................581
19.4.4 S I P网络接口层的输入函数.....................................583
19.4.5 S I P网络接口层的输出函数.....................................586
19.5 S I P网络协议栈的A R P 层............................................ 588
19.5.1 SIP地址解析层的架构......................................... 588
19.5.2 SIP地址解析层的数据结构.....................................588
19.5.3 SIP地址解析层的映射表.......................................590
19.5.4 SIP地址解析层的A R P 映射表维护函数......................... 591
19.5.5 SIP地址解析层的A R P 网络报文构建函数.... :..................593
19.5.6 S1P地址解析层的A R P 网络报文收发处理函数................... 595
19.6 S I P网络协议栈的IP层.............................................. 598
19.6.1 S I P网际协议层的架构......................................... 598
19.6.2 S I P网际协议层的数据结构.....................................599
19.6.3 S I P网际协议层的输入函数.....................................601
19.6.4 S I P网际协议层的输出函数.....................................605
19.6.5 S I P网际协议层的分片函数.....................................606
19.6.6 S I P网际协议层的分片组装函数................................ 607
19.7 S I P网络协议栈的I C M P层........................................... 611
19.7.1 SIP控制报文协议的数据结构.................................. 611
19.7.2 SIP控制报文协议的协议支持...................................612
19.7.3 SIP控制报文协议的输入函数.................................. 613
19.7.4 SIP控制报文协议的回显应答函数.............................. 614
19.8 S I P网络协议栈的U D P 层............................................ 615
19.8.1 SIP数据报文层的数据结构.....................................615
19.8.2 SIP数据报文层的控制单元.....................................615
19.8.3 SIP数据报文层的输入函数.....................................617
19.8.4 SIP数据报文层的输出函数.....................................618
19.8.5 SIP数据报文层的建立函数.....................................618
19.8.6 SIP数据报文层的释放函数.....................................619
19.8.7 SIP数据报文层的绑定函数.....................................620
19.8.8 SIP数据报文层的发送数据闲数.................................621
19.8.9 SIP数据报文层的校验和计算...................................622
19.9 S I P网络协议栈的协议无关层......................................... 623
19.9.1 SIP协议无关层的系统架构.....................................623
• XIX •
19.9.2 SIP协议无关层的函数形式.....................................624
19.9.3 S1P协议无关层的接收数据函数................................ 624
19.10 S I P网络协议栈的B S D 接U 层....................................... 625
19.10.1 S IP用户接口层的架构........................................ 625
19.10.2 SIP用户接n 层的套接字建立函数............................. 626
19.10.3 SIP用户接M 层的套接字关闭函数............................. 627
19.10.4 SIP用户接U 层的套接字绑定函数............................. 627
19.10.5 SIP用户接丨」层的套接字连接函数............................. 628
19.10.6 SIP用户接U 层的套接字接收数据函数......................... 628
19.10.7 SIP用户接口层的发送数据函数................................629
19.11 S I P网络协议找的编译.............................................. 630
19.11.1 SI P的文件结构.............................................. 630
19.11.2 SIP 的 Makefile.............................................. 631
19.11.3 SIP的编译运行.............................................. 631
19.12 小结..............................................................631
第2 0章一个简单防火墙的例子S I P F W .......................................633
20.1 S I P F W防火墙的功能描述............................................ 633
20.1.1 S I P F W防火墙对主机进行网络数据过滤的功能描述............... 633
20.1.2 S I P F W防火墙用户设置防火墙规则的功能描述................... 634
20.1.3 S I P F W防火墙配K 文件等附加功能的功能描述................... 634
20.2 SIPFW 需求分析.................................................... 634
20.2.1 S I P F W防火墙条件和动作......................................635
20.2.2 S I P F W防火墙支持过滤的类型和内容........................... 635
20.2.3 S I P F W防火墙过滤的方式和动作............................... 638
20.2.4 S I P F W防火墙的配置文件...................................... 640
20.2.5 S I P F W防火墙命令行配置格式..................................640
20.2.6 S I P F W防火墙的规则文件格式..................................642
20.2.7 S I P F W防火墙的日志文件数据格式............................. 643
20.2.8 S I P F W防火墙构建所采用的技术方案........................... 644
2 0 . 3使用netlink进行用户空间和内核空间数据交S ......................... 645
20.3.1 netlink的用户空间程序设计.................................... 645
20.3.2 netlink 的内核空间 A P I........................................ 648
2 0 . 4使用proc进行内存数据用户空间映射..................................650
20.4.1 proc虚拟文件系统的结构...................................... 650
20.4.2 创建proc虚拟文件........................................... 651
2 0 . 4 . 3删除proc虚拟文件........................................... 652
20.4.4 proc文件的写函数............................................ 652
20.4.5 proc文件的读函数............................................ 653
2 0 . 5内核空间的文件操作函数............................................ 654
• XX •
20.5.1 内核空间的文件结构.......................................... 654
20.5.2 内核空间的文件建立操作...................................... 655
20.5.3 内核空间的文件读写操作...................................... 656
20.5.4 内核空间的文件关闭操作...................................... 657
20.6 S I P F W防火墙的模块分析和设计......................................657
20.6.1 S I P F W防火墙的总体架构...................................... 657
20.6.2 S I P F W防火墙的用户命令解析................................. 660
20.6.3 S I P F W用户空间与内核空间的交互............................. 663
20.6.4 S I P F W防火墙内核链h 的规则处理............................. 666
20.6.5 S I P F W防火墙的P R O C 虑拟文件系统........................... 668
20.6.6 S I P F W防火墙的配置文件和口志文件处理....................... 669
20.6.7 S I P F W防火墙的过滤模块设计................................. 671
20.7 S I P F W防火墙各功能模块的实现......................................673
20.7.〗 S I P F W防火墙的命令解析代码................................. 674
20.7.2 S I P F W防火墙的过滤规则解析模块代码......................... 678
20.7.3 S I P F W防火墙的网络数据拦截模块代码......................... 680
20.7.4 S I P F W防火墙的P R O C 虚拟文件系统........................... 681
20.7.5 S I P F W防火墙对配置文件的解析............................... 683
20.7.6 S I P F W防火墙内核模块初始化和退出........................... 684
2 0 . 7 . 7用户空间处理主函数.......................................... 685
20.8 编译、调试和测试.......................... ....................... 686
2 0 . 8 . 1用户程序和内核程序的Makefile................................ 686
20.8.2 编译及运行.................................................. 687
2 0 . 8 . 3下发过滤规则,测试过滤结果.................................. 688
20.9 小结.............................................................. 690
ctrl+c和ctrl+z都是中断命令,但是他们的作用却不一样.
ctrl+c是强制中断程序的执行,
而ctrl+z的是将任务中断,但是此任务并没有结束,他仍然在进程中他只是维持挂起的状态,用户可以使用fg/bg操作继续前台或后台的任务,fg命令重新启动前台被中断的任务,bg命令把被中断的任务放在后台执行.
当你vi一个文件是,如果需要用shell执行别的操作,但是你又不打算关闭vi
一、动态库so文件和可执行文件m在同一个目录下,然后执行可执行文件,问题来了,提示:
./m: error while loading shared libraries: libcac.so: cannot open shared object file: No such file or directory
在Windows中,可执行程序在运行时,加载动态链接库时,会在系统目录、环境变量指定的目录...
函数库一般分为静态库和动态库两种。
静态库:
是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。
动态库:
与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,gcc/g++在编译时默认使用动态库...
静态链接库LIB和动态链接库DLL静态链接库与动态链接库----C/C++[编译链接装载]之静态链接C++静态库与动态库态链接与动态链接的区别
1. 库简介库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so,libhello.a。为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0。由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。ln -s libhello.so.1.0 libhello.so.1ln -s...
类库:类库就是代码的集合,类库是给开发者共享代码使用的类库分为: 静态库和动态库静态库: .a和.framework链接时,静态库中使用的文件会被完整的复制到可执行文件中,被多次使用就有多分冗余拷贝动态库: .dylib和.framework(iOS9取消了.dylib,使用.tbd替代)链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序公用,节省内存动态库相对来...
文章目录静态链接动态链接
说起静态链接和动态链接,大家肯定都不陌生。静态链接与动态链接的差别顾名思义,动态链接使动态库中的函数在程序运行后,才被用到;而静态链接则在运行前,就将所需函数合并了。
我们来看看两者在 Linux 下的定义:
静态链接
静态链接:Linux 下的静态链接器(static linker)以一组可重定位目标文件和命令行参数作为输人,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出。
所有的编译系统都提供一种机制,将所有相关的目标模块打包成为一个单独的文件,称为静态库(stat
在/etc/ld.so.conf.d/下创建xxx.conf,在文本中加入.so所在路径,如:/usr/xxx等等,然后使用相应ldconfig命令使之生效。
将.so所在路径添加为PATH环境变量。
在编译命令中使用-Wl,-rpath=./参数,并将相应.so拷贝到执行目录;当然也可以将‘./’指定为其他目录。
注意:-L参数添加的lib搜索目录只用于编译时,运行时需使用上述方法之一,否则...
1、在开发过程中如果要将可执文件与动态链接库及依赖文件分开,也就是在.exe同级目录下新建一个文件夹放置.dll 文件和依赖文件,以方图SDK为例:
2、将动态链接库单独分开
在程序启动入口main()设置DLL目录(设置当前可执行文件的相对路径),添加SetDllDirectory("./Authen/bin");(要添加头文件#include <Windows.h>,如果头文件报错,在项目属性->VC++目录->包含目录中,添加 $(WindowsSDK_