1. 安装 sudo apt-get install vsftpd //ubuntu中有很多种ftp服务器,此处选择安装vsftpd服务器
2. 配置 sudo vi /etc/vsftpd.conf
尽量不要手写内容到文件中。通过打开、关闭注释的方式调整该文件。
3. 启动 (重启——如果修改过配置必须重启)
sudo service vsftpd restart
4. 客户端发起链接
ftp 127.0.0.1(自己充当服务器、自己充当客户端)
ftp 192.168.36.xxx(对方IP)
5. 数据传递(上传、下载)
下载:get 非目录
上传:put 非目录
6. 关闭连接
quit/exit/bye
/etc/passwd
中可查到默认ftp服务器的开放目录。1. 创建匿名用户登录位置。
cat /etc/passwd | grep ftp 查找本机默认指定 匿名用户登录位置。——/srv/ftp
2. sudo mkdir /srv/ftp/incoming
//此处之所以要在默认登录文件夹位置里再创建一个子文件夹,
//是因为默认位置文件夹的权限限制用户ftp对该目录进行写操作,后果是不能使用put上传文件到该服务器目录
//默认文件夹的权限见下图
//虽然简单粗暴的方法是修改这个默认登录文件夹的权限对同组用户开放写权限,
//不过更好的方式是在该目录下新建一个为用户ftp所有的子文件夹,
//以后每次登录上ftp服务器后都对应地进入默认登录文件夹下的指定子文件夹进行上传和下载操作。
//这样,当多个用户连接上同一个ftp服务器时各自对应操作不同的文件夹,更有条理。子文件夹权限设置见以下第三步。
3. sudo chown ftp:nogroup /srv/ftp/incoming ——所有者:ftp 所属组:nogroup
//此处是修改incoming文件夹的权限为用户ftp所有,见下图
4. 修改配置文件,给匿名用户开放各种权限。/etc/vasftpd.conf
5. sudo service vsftpd restart
6. ps aux | grep ftp ——查询结果应为2+ 才表示启动成功
7. ftp 127.0.0.1 ——用户名:anonymous 密码:回车
8. 默认匿名用户登录上以后在/srv/ftp(默认)
9. cd incoming (注意目录权限)
10 put 上传 get 下载。
其中,ftp用户拥有第二组(同一组内)权限。
其中,ftp用户拥有第一组(所有者)权限。
- 但是。ftp服务器只能上传和下载文件而不能操作不能文件夹,因此引出 lftp 服务器。
lftp使用:
1. sudo apt-get install lftp 安装lftp客户端
2. 配置vsftpd.conf(与ftp共享同一个配置文件)
3. restart
4. 登录lftp 127.1
5. login itcat/anonymous (匿名用户可省略该步)
6. mirror -R 上传目录
7. mirror 目录下载
8. bye
另外,lftp 下的中文默认使用UTF-8,可正确显示中文;而ftp 下的中文为乱码。因此,推荐使用 lftp。
nfs使用流程:
1.安装:sudo apt-get install nfs-kernel-server
2.创建一个欲共享出去的目录 如:/home/itcast/itcast
3.打开配置文件:sudo vi /etc/exports
4.写入共享目录的绝对路径,及对应权限。如:
/home/itcast/itcast *(ro,sync,no_root_squash)
5.重启nfs
sudo /etc/init.d/nfs-kernel-server restart
-------------------------
6.客户端访问共享目录:
sudo mount 192.168.43.75:/home/itcast/itcast/ /mnt
7. cd 到本机的/mnt 目录中就可以使用cp命令得到目录中的所有文件。
【常见错误】:1. 虚拟机下出现“不能mount实体”错误时,需在mount之前使用
install nfs-common 即可解决。
2. 出现“超级坏块儿”错误无法挂载,多是因为没有安装nfs-kernel-server导致。
对比语法格式:
nfs:sudo mount 192.168.43.75:/home/itcast/itcast/ /mnt
ssh: ssh itcast@192.168.43.75 ——>yes 密码
scp -r itcast@192.168.43.75:/home/itcast/aa ../
在这四个过程中,编译过程耗时最长,因为编译要逐条检查语法错误,然后和标准语法比对。
若程序包括自己写的头文件但该头文件不在程序所在的同一个文件夹下,就使用 -I 参数后接这个自定义头文件所在的文件夹。
objdump -dS后接目标文件(.o)或可执行文件(.out)可反汇编二进制文件为汇编程序。
- 可执行程序(.out)运行起来后被加载到内存中,那么可执行程序在内存中的布局是怎么的呢?
上图是32位内存空间的布局:
最上面为内核区(kernel),下面为用户区(user)。用户无权访问内核区。对于用户区,从低地址开始向上:
最下面为ELF header,记录ELF文件的属性信息;
上面为.text区,即代码段,存放代码(只读);
上面为ordata区,存放常量(只读);
上面为.data区,即数据段,存放全局变量;
上面为.bss区,存放未初始化的全局变量和静态局部变量;
上面为堆区,生长方向为从低地址到高地址;
用户区最上面为栈区,生长方向为从高地址向低地址。
当栈和堆生长到彼此接触时,则表明发生了内存溢出!
栈中存放的是一个个栈帧,即函数调用的存储子空间,栈帧中具体存放的是被调用函数的局部变量和临时值,临时值保存的是被调函数的返回地址,被调函数的形参(若有)和其内部的局部变量等价。
1. gcc add.c sub.c mul.c -c ——>得到*.o
2. ar rs libmymath.a add.o sub.o mul.o ——>得到静态库
ar工具不包含在gcc中
r更新、c创建、s建立索引
file libmymath.a ——>查看库信息
3. gcc main.c -L ./ -l mymath -I ./ -o app ——>使用静态库
使用:L:指定静态库所在目录位置;l:指定静态库名字(此处为去掉lib前缀和.a后缀后的名字) I:指定头文件所在目录位置
gcc add.c sub.c mul.c main.c -o app
1. gcc -fPIC add.c mul.c sub.c -c (-fPIC:生成“与位置无关”的目标文件*.o)
2. gcc -shared -o libmymath.so add.o mul.o sub.o
3. gcc main.c -L库路径 -l库名 -I头文件名 -o app
4. ./app --> 出错
原因:动态连接器 ld-linux.so.2 搜寻动态库的路径未指定,
执行ldd app发现动态链接器找不到 libmymath 库。
指定方法(推荐第3、4种方法):
1). 环境变量法:export LD_LIBRARY_PATH=./ 将当前目录加入环境变量,但是终端退出了就无效了。
2). 配置文件法:将上条写入家目录下.bashrc文件中 (永久生效,设置到~/.bashrc)
3). 拷贝法:直接将libmymath.so文件拷贝到/usr/lib/目录下。
(受libc库的启发,因为动态链接器在搜索标准C库时会去这个目录下找,而且也说明标准C库也是一个动态库)
4). 缓存文件法:将libmymath.so所在绝对路径加入到/etc/ld.so.conf文件(保存动态链接器默认搜索动态库的路径),
使用sudo ldconfig -v 动态更新/etc/ld.so.cache文件(2进制文件,
它是实际真正影响动态库加载路径的文件,但由于是二进制文件,不方便直接修改它,因此通过修改上面这个.conf文件来影响它。)
动态库的规范使用方法:
5. 指定动态库的soname
gcc -shared -Wl,-soname,libmymath.so.1 -o libmymath.so.1.10 add.o mul.o sub.o
soname的作用是隐藏库的实现细节,不让用户知晓版本调整细节信息。
6.创建动态库的LinkerName
ln -s libmymath.so.1.10 libmymath.so
也即创建动态库的软链接,在使用这个动态库联合编译时就是用的是它的软链接名。
命令 | 简写 | 作用 |
---|---|---|
help | h | 按模块列出命令类 |
help class | 查看某一类型的具体命令 | |
list | l | 查看代码,可跟行号和函数名 |
quit | q | 退出gdb |
run | r | 全速运行程序 |
start | 单步执行,运行程序,停在第一行执行语句 | |
next | n | 逐过程执行 |
step | s | 逐语句执行,遇到函数,跳到函数内执行 |
backtrace | bt | 查看函数的调用的栈帧和层级关系 |
info | i | 查看GDB内部局部变量的数值,info breakpoints |
frame | f | 切换函数的栈帧 |
finish | 结束当前函数,返回到函数调用点 | |
set | 设置变量的值set var n=100 | |
run argv[1] argv[2] | 调试时命令行传参 | |
p | 打印变量和地址 | |
break | b | 设置断点,可根据行号和函数名 |
delete | d | 删除断点d breakpoints NUM |
display | 设置观察变量 | |
undisplay | 取消观察变量 | |
continue | c | 继续全速运行剩下的代码 |
enable breakpoints | 启用断点 | |
disable breakpoints | 禁用断点 | |
x | 查看内存x /20xw 显示20个单元,16进制,4字节每单元 | |
watch | 被设置观察点的变量发生修改时,打印显示 | |
i watch | 显示观察点 | |
core文件 | ulimit -c 1024 开启core文件,调试时gdb a.out core |
makefile
或Makefile
。里面都是一组一组的规则:目标、依赖条件、命令。 //变量定义和使用:
//1、变量定义直接用'='
//2、使用变量值用$(变量名)
foo = abc
bar = $(foo) //索引变量值
//手动定义了两个变量:foo、bar,其中bar的值是foo变量值的引用。
//**自动变量**:
$@:在命令中表示规则中的目标
$<:在命令中表示规则中的第一个条件
$^:在命令中表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复的项则消除重复项。
通常我们在Makefile中会定义一些变量,方便Makefile的修改维护。
//以下列形式代替多组相同形式的规则
%.o:%.c
%:%.c
$(target):%:%.c //静态模式规则,针对某个集合来使用该组模式,比如:
$(obj):%.o:%.c
$(CC) -c $< -o $@
//上句静态模式规则的含义是,把变量obj中的每个成员都用这条模式规则来生成
$(CC) –c $(CFLAGS) $(CPPFLAGS) $< -o $@
//其中,“$@”表示依次取出目标值,$<表示依次取出依赖条件。
//注意:只有写成模式规则的时候,$<才表示了所有依赖条件的依次取值
//否则只是取依赖条件中的第一个。
src = $(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
obj = $(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
clean:没有依赖,只有命令
1) 用途:清除编译生成的中间.o文件和最终目标文件
2) make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令
3) 伪目标声明:.PHONY:clean
所谓伪目标,是makefile中无论其依赖条件满足或不满足,该规则都会执行
4) clean命令中的特殊符号
– “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
– “@”不显示命令本身,只显示结果。如:“@echo”clean done“”
其它
– ALL:指定最终要生成的目标
– make -n:只打印要执行的命令,不会真正执行命令
– make -f:执行一个名称为非makefile/Makefile
的文件
– make 默认执行第一个出现的目标,可通过make dest指定要执行的目标
– distclean目标
– install目标
– make -C 指定目录进入指定目录,调用里面的Makefile