网络原理-计算机网络详解-传输层之UDP协议

数据单位

UDP 传送的数据单位协议是 UDP 报文或用户数据报


特点

UDP 是无连接的,即发送数据之前不需要建立连接

UDP 使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制

UDP 是面向报文的.UDP 没有拥塞控制,很适合多媒体通信的要求

UDP 支持一对一、一对多、多对一和多对多的交互通信

UDP 的首部开销小,只有 8 个字节


具体实现

发送方 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层.UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界

应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文

接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整的报文


要求

应用程序必须选择合适大小的报文


UDP首部格式

说明:

  • 户数据报 UDP 有两个字段:数据字段和首部字段.首部字段有 8 个字节,由 4 个字段组成,每个字段都是两个字节
  • 在计算检验和时,临时把“伪首部”和UDP用户数据报连接在一起,伪首部仅仅是为了计算检验和

图释:

首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。【也就是说伪首部不会添加到数据包里面】

抓包过后才发现,ip数据包首部没有添加可选项,就直接装载 udp数据了。


发送UDP请求的客户端图释

参考:

http://www.cnblogs.com/kzang/articles/2582879.html

wordpress-优化php-fpm和mysql

个人小站,用VPS 搭建了  wordpress,因为系统配置低,所以需要优化一下。

一、优化 php-fpm

#用于查找配置文件
 find / -name php.ini
#结果  /etc/php.ini
ls /etc
#发现  /etc/php-fpm.conf  里面 调用了 /etc/php-fpm.d  这个是文件夹
# 进入   cd /etc/php-fpm.d
修改  pm.max_children 等参数

php-fpm进程设置多少合适,设成动态还是静态?

lnmp一键安装包》中会根据你服务器内存调整php-fpm进程数。

下面是摘自Google讨论话题:《 PHP-FPM on highload tips 》如果你的高负载网站使用PHP-FPM管理FastCGI,也许下面这些技巧对你有用

1、系统上优化


1. Increase Linux “max open files”, using the following command (must be root):

Linux下增加文件打开数,命令如下:

cat >> /etc/security/limits.conf <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF

可以用 ulimit -n 命令查看。

2. Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;

socket连接FastCGI,/dev/shm是内存文件系统,socket放在内存中肯定会快些。

nginx 下的配置
&nbsp;location ~ \.php$ {
   #fastcgi_pass 127.0.0.1:9000;
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
}


systemctl restart nginx [这里可能会报错 unknown directive "fastcgi_pass" 其实是因为配置包含的空格中有一些 dirty EOL(end of line) characters,重新删除添加即可]

##################################### 

修改php-fpm.conf
;listen = 127.0.0.1:9000
listen = /dev/shm/php-fcgi.sock

# 执行下面这句话,会自动生成一个 /dev/shm/php-fcgi.sock 但是文件权限不对
systemctl restart php-fpm # 所以我又添加了权限 chmod 777 /dev/shm/php-fcgi.sock


# 原因是一开始忘记添加了下面两句话,导致生成的 php-fcgi.sock 是root所有,存在权限问题
listen.owner = apache # 这里要设置网站所有者,目标权限统一
listen.group = apache # 这里要设置网站所有者,目标权限统一 
# 但是又出问题了,于sock 文件是 nginx 和 php-fpm共享的,所以nginx和php-fpm的进程需要设置成同一个用户,权限统一

##################################### 
ps aux|grep nginx     # 发现 是 nginx 用户所有
ps aux|grep php-fpm   # 发现 是 apache 用户所有

nginx的用户名在/etc/nginx/nginx.conf配置文件中,有一个user参数,查看对应的就可以。
后来浏览器访问时,发现页面加载不全,net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
百度后知道,nginx目录下fastcgi_temp属于nginx用户和用户组,还需要修改成 apache
chown  -R  apache:apache /etc/nginx/fastcgi_params

查看 php-fpm 配置文件
#vi /etc/php-fpm.d/www.conf
 
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
;user = nobody
user=apache
; RPM: Keep a group allowed to write in log dir.
;group = nobody
group=apache

# 后来发现 nginx 日志中:open() "/var/cache/nginx/fastcgi_temp/3/00/0000000003" failed (13: Permission denied) while reading
# 于是我 rm -rf /var/cache/nginx/  然后发现重启 nginx 报错,mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory)
# 于是我 mkdir /var/cache/nginx

mkdir /var/cache/nginx

 

Unix域Socket因为不走网络,的确可以提高Nginx和php-fpm通信的性能,但在高并发时会不稳定。
Nginx会频繁报错:
     connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream

可以通过下面两种方式提高稳定性:
1)调高nginx和php-fpm中的backlog
     配置方法为:在nginx配置文件中这个域名的server下,在listen 80后面添加default backlog=1024。
     同时配置php-fpm.conf中的listen.backlog为1024,默认为128。
2)增加sock文件和php-fpm实例数
     再新建一个sock文件,在Nginx中通过upstream模块将请求负载均衡到两个sock文件背后的两套php-fpm实例上。

 

3. Compile PHP’s modules as less as possible, the simple the best (fast);

尽量少安装PHP模块,最简单是最好(快)的

妈蛋的 一个 php-fpm 占了80M
# 查看装了哪些 php 模块 ;卸载只要  yum remove 模块名
rpm -qa | grep php

# 下面是 必须要装的模块
php71w-common-7.1.22-1.w7.x86_64 【这个才是真正的主模块】
php71w-cli-7.1.22-1.w7.x86_64
php71w-mysql-7.1.22-1.w7.x86_64
php71w-pdo-7.1.22-1.w7.x86_64
php71w-fpm-7.1.22-1.w7.x86_64

# 下面是没有必要装的
mod_php71w-7.1.22-1.w7.x86_64  【这个模块应该是独立于其他模块的,可以删除,因为卸载7.1版本时,这个模块根本就没有删除】
php71w-xml-7.1.22-1.w7.x86_64
php71w-soap-7.1.22-1.w7.x86_64
php71w-mcrypt-7.1.22-1.w7.x86_64
php71w-xmlrpc-7.1.22-1.w7.x86_64
php71w-gd-7.1.22-1.w7.x86_64  // 作用是 png 转成 jpg

4. Using PHP code accelerator, e.g eAccelerator, XCache. And set “cache_dir” to /dev/shm on Linux.

使用php代码加速器,有那些PHP Opcode缓存插件?
Optimizer+(Optimizer+于2013年3月中旬改名为Opcache,PHP 5.5集成Opcache,其他的会不会消失?)、eAccelerator、xcache、APC …,例如 eAccelerator, XCache.在Linux平台上可以把`cache_dir`指向 /dev/shm

Opcache 缓存默认就存放在内存中,所以不需要指定目录了。

yum install php-opcache
# 相关配置
# vim /etc/php.d/10-opcache.ini

# 安装完后,直接用wordpress 的 W3 Total Cache 插件设置缓存 到这里就行了。

===============================
可以安装 redis 服务,启动服务端后,需要 php的 驱动
yum list | grep php72w*  ## 从网上查找所有的 php 插件
yum install php72w-pecl-redis  
## PECL is a repository for PHP Extensions, providing a directory of all known extensions and hosting facilities for downloading and development of PHP extensions.
安装完 redis 驱动后 ,直接用wordpress 的 W3 Total Cache 插件设置缓存 到这里就行了

2、php-fpm 配置文件优化


1. Increas PHP FastCGI child number to 100 and even more. Sometime, 200 is OK! ( On 4GB memory server);

把你的PHP FastCGI子进程数调到100或以上,在4G内存的服务器上200就可以(建议压力测试来得出自己服务器合理的值)其实就是 php-fpm 进程数
配置文件/etc/php-fpm.conf --> /etc/php-fpm.d/www.conf
这个配置文件的里面的池名[www] 就对应网站的域名 ,两者互相对应。这个配置文件即可以用来设置 php-fpm 运行时的用户名和用户组,也可以生成 sock文件,并规定用户名和用户组。

; Start a new pool named 'www'.
[www]

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = apache
; RPM: Keep a group allowed to write in log dir.
group = apache

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /dev/shm/php-fcgi.sock

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
;                 mode is set to 0660
;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
listen.owner = apache
listen.group = apache

# 查看php-fpm的进程个数
ps -fe |grep "php-fpm"|grep "pool"|wc -l

# 查看每个php-fpm占用的内存大小
ps -ylC php-fpm --sort:rss

# 配置php-fpm参数
pm = dynamic #动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗。
#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:

pm.max_children #子进程最大数
pm.start_servers #启动时的进程数
pm.min_spare_servers #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers #保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

###  我的 1G 主机,测试使用发现  一个 php-fpm 占了80M,所以进程配置了最多10个

2.其他参数

rlimit_files = 51200
Increase PHP-FPM open file description rlimit:增加 PHP-FPM 打开文件描述符的限制。

pm.max_requests = 10240;
每个请求完成后php-cgi会回收内存,但是不会释放给操作系统,这样就会导致大量内存被php-cgi占用。官方的解决办法是降低PHP_FCGI_MAX_REQUESTS的值,如果用的是php-fpm,对应的php-fpm.conf中的就是max_requests,该值的意思是发送多少个请求后会重启该线程,我们需要适当降低这个值,用以让php-fpm自动的释放内存,不是大部分网上说的51200等等。

request_terminate_timeout = 30;
最大执行时间, 在php.ini中也可以进行配置(max_execution_time)默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。可以使用 request_terminate_timeout = 30s,但是如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。php-cgi进程数不够用、php执行时间长、或者是php-cgi进程死掉,都会出现502错误。

用strace跟踪 超时进程:
利用nohup将strace转为后台执行,直到attach上的php-fpm进程死掉为止:
nohup strace -T -p 13167 > 13167-strace.log &

参数说明:

-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-o filename,则所有进程的跟踪结果输出到相应的filename
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认为40.
-e execve 只记录 execve 这类系统调用
-p 主进程号

request_slowlog_timeout = 2; 配置输出php-fpm慢日志,阀值为2秒:
slowlog =/tmp/www.slow.log; 慢日志路径,可以自己定路径。
利用sort/uniq命令分析汇总php-fpm慢日志:

[root@b28-12 log]# grep -v "^$" www.log.slow.tmp | cut -d " " -f 3,2 | sort | uniq -c | sort -k1,1nr | head -n 50

   5181 run() /www/test.net/framework/web/filters/CFilter.php:41

   5156 filter() /www/test.net/framework/web/filters/CFilterChain.php:131

   2670 = /www/test.net/index.php

   2636 run() /www/test.net/application/controllers/survey/index.php:665

   2630 action() /www/test.net/application/controllers/survey/index.php:18

   2625 run() /www/test.net/framework/web/actions/CAction.php:75

   2605 runWithParams() /www/test.net/framework/web/CController.php:309

   2604 runAction() /www/test.net/framework/web/filters/CFilterChain.php:134

   2538 run() /www/test.net/framework/web/CController.php:292

   2484 runActionWithFilters() /www/test.net/framework/web/CController.php:266

   2251 run() /www/test.net/framework/web/CWebApplication.php:276

   1799 translate() /www/test.net/application/libraries/Limesurvey_lang.php:118

   1786 load_tables() /www/test.net/application/third_party/php-gettext/gettext.php:254

   1447 runController() /www/test.net/framework/web/CWebApplication.php:135

参数解释:
sort:  对单词进行排序
uniq -c:  显示唯一的行,并在每行行首加上本行在文件中出现的次数
sort -k1,1nr:  按照第一个字段,数值排序,且为逆序
head -10:  取前10行数据

3、PHP性能监控


常用的方法就是开启xdebug的性能监控功能,将xdebug输出结果通过WinCacheGrind软件分析。
xdebug的安装和配合IDE调试的方法参见:Vim+XDebug调试PHP

php.ini中配置的这几项是输出性能信息的:

xdebug.auto_trace = on

xdebug.auto_profile = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.trace_output_dir = "/tmp"
xdebug.profiler_output_dir ="/tmp"

这样XDebug会输出所有执行php函数的性能数据,但产生的文件也会比较大。可以关闭一些选项如collect_params、collect_return,来减少输出的数据量。或者关闭自动输出,通过在想要监控的函数首尾调用xdebug函数来监控指定的函数。输出的文件名类似cachegrind.out.1277560600和trace.3495983249.txt,可以拿到Windows平台下用WinCacheGrind进行图形化分析。

在线监测:

# nginx 配置
location ~ ^/status$ {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
}

# php-fpm配置
pm.status_path = /status

###############################
这样的话通过http://域名/status就可以看到当前的php情况

  下面介绍每个参数的作用:
  pool:php-fpm池的名称,一般都是应该是www
  process manage:进程的管理方法,php-fpm支持三种管理方法,分别是static,dynamic和ondemand,一般情况下都是dynamic
  start time:php-fpm启动时候的时间,不管是restart或者reload都会更新这里的时间
  start since:php-fpm自启动起来经过的时间,默认为秒
  accepted conn:当前接收的连接数
  listen queue:在队列中等待连接的请求个数,如果这个数字为非0,那么最好增加进程的fpm个数
  max listen queue:从fpm启动以来,在队列中等待连接请求的最大值
  listen queue len:等待连接的套接字队列大小
  idle processes:空闲的进程个数
  active processes:活动的进程个数
  total processes:总共的进程个数
  max active processes:从fpm启动以来,活动进程的最大个数,如果这个值小于当前的max_children,可以调小此值
  max children reached:当pm尝试启动更多的进程,却因为max_children的限制,没有启动更多进程的次数。如果这个值非0,那么可以适当增加fpm的进程数
  slow requests:慢请求的次数,一般如果这个值未非0,那么可能会有慢的php进程,一般一个不好的mysql查询是最大的祸首。

二、优化mysql

my.cnf  【经过使用,目前mysql5.7版本,使用默认配置,内存占用稳定在20%左右,我也懒得优化了】

MySQL 5.6版本适合在1GB内存VPS上的my.cnf配置文件(点击这里下载文件):

[client]  
port = 3306  
socket = /tmp/mysql.sock  
  
[mysqld]  
port = 3306  
socket = /tmp/mysql.sock  
  
basedir = /usr/local/mysql  
datadir = /data/mysql  
pid-file = /data/mysql/mysql.pid  
user = mysql  
bind-address = 0.0.0.0  
server-id = 1 #表示是本机的序号为1,一般来讲就是master的意思  
  
skip-name-resolve  
# 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,  
# 则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求  
  
#skip-networking  
  
back_log = 600  
# MySQL能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,  
# 然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。  
# 如果期望在一个短时间内有很多连接,你需要增加它。也就是说,如果MySQL的连接数据达到max_connections时,新来的请求将会被存在堆栈中,  
# 以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。  
# 另外,这值(back_log)限于您的操作系统对到来的TCP/IP连接的侦听队列的大小。  
# 你的操作系统在这个队列大小上有它自己的限制(可以检查你的OS文档找出这个变量的最大值),试图设定back_log高于你的操作系统的限制将是无效的。  
  
max_connections = 1000  
# MySQL的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。可以过'conn%'通配符查看当前状态的连接数量,以定夺该值的大小。  
  
max_connect_errors = 6000  
# 对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST。  
  
open_files_limit = 65535  
# MySQL打开的文件描述符限制,默认最小1024;当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个,  
# 当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个。  
  
table_open_cache = 128  
# MySQL每打开一个表,都会读入一些数据到table_open_cache缓存中,当MySQL在这个缓存中找不到相应信息时,才会去磁盘上读取。默认值64  
# 假定系统有200个并发连接,则需将此参数设置为200*N(N为每个连接所需的文件描述符数目);  
# 当把table_open_cache设置为很大时,如果系统处理不了那么多文件描述符,那么就会出现客户端失效,连接不上  
  
max_allowed_packet = 4M  
# 接受的数据包大小;增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或MySQLd必须返回大的结果行时MySQLd才会分配更多内存。  
# 该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。  
  
binlog_cache_size = 1M  
# 一个事务,在没有提交的时候,产生的日志,记录到Cache中;等到事务提交需要提交的时候,则把日志持久化到磁盘。默认binlog_cache_size大小32K  
  
max_heap_table_size = 8M  
# 定义了用户可以创建的内存表(memory table)的大小。这个值用来计算内存表的最大行数值。这个变量支持动态改变  
  
tmp_table_size = 16M  
# MySQL的heap(堆积)表缓冲大小。所有联合在一个DML指令内完成,并且大多数联合甚至可以不用临时表即可以完成。  
# 大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。  
# 如果某个内部heap(堆积)表大小超过tmp_table_size,MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说,如果调高该值,MySQL同时将增加heap表的大小,可达到提高联接查询速度的效果  
  
read_buffer_size = 2M  
# MySQL读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。  
# 如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能  
  
read_rnd_buffer_size = 8M  
# MySQL的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,  
# MySQL会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySQL会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大  
  
sort_buffer_size = 8M  
# MySQL执行排序使用的缓冲大小。如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。  
# 如果不能,可以尝试增加sort_buffer_size变量的大小  
  
join_buffer_size = 8M  
# 联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享  
  
thread_cache_size = 8  
# 这个值(默认8)表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,  
# 如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,  
# 增加这个值可以改善系统性能.通过比较Connections和Threads_created状态的变量,可以看到这个变量的作用。(–>表示要调整的值)  
# 根据物理内存设置规则如下:  
# 1G  —> 8  
# 2G  —> 16  
# 3G  —> 32  
# 大于3G  —> 64  
  
query_cache_size = 8M  
#MySQL的查询缓冲大小(从4.0.1开始,MySQL提供了查询缓冲机制)使用查询缓冲,MySQL将SELECT语句和查询结果存放在缓冲区中,  
# 今后对于同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果。根据MySQL用户手册,使用查询缓冲最多可以达到238%的效率。  
# 通过检查状态值'Qcache_%',可以知道query_cache_size设置是否合理:如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况,  
# 如果Qcache_hits的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;如果Qcache_hits的值不大,则表明你的查询重复率很低,  
# 这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。此外,在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲  
  
query_cache_limit = 2M  
#指定单个查询能够使用的缓冲区大小,默认1M  
  
key_buffer_size = 4M  
#指定用于索引的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,  
# 系统将开始换页并且真的变慢了。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态值Key_read_requests和Key_reads,  
# 可以知道key_buffer_size设置是否合理。比例key_reads/key_read_requests应该尽可能的低,  
# 至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE 'key_read%'获得)。注意:该参数值设置的过大反而会是服务器整体效率降低  
  
ft_min_word_len = 4  
# 分词词汇最小长度,默认4  
  
transaction_isolation = REPEATABLE-READ  
# MySQL支持4种事务隔离级别,他们分别是:  
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.  
# 如没有指定,MySQL默认采用的是REPEATABLE-READ,ORACLE默认的是READ-COMMITTED  
  
log_bin = mysql-bin  
binlog_format = mixed  
expire_logs_days = 30 #超过30天的binlog删除  
  
log_error = /data/mysql/mysql-error.log #错误日志路径  
slow_query_log = 1  
long_query_time = 1 #慢查询时间 超过1秒则为慢查询  
slow_query_log_file = /data/mysql/mysql-slow.log  
  
performance_schema = 0  
explicit_defaults_for_timestamp  
  
#lower_case_table_names = 1 #不区分大小写  
  
skip-external-locking #MySQL选项以避免外部锁定。该选项默认开启  
  
default-storage-engine = InnoDB #默认存储引擎  
  
innodb_file_per_table = 1  
# InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间  
# 独立表空间优点:  
# 1.每个表都有自已独立的表空间。  
# 2.每个表的数据和索引都会存在自已的表空间中。  
# 3.可以实现单表在不同的数据库中移动。  
# 4.空间可以回收(除drop table操作处,表空不能自已回收)  
# 缺点:  
# 单表增加过大,如超过100G  
# 结论:  
# 共享表空间在Insert操作上少有优势。其它都没独立表空间表现好。当启用独立表空间时,请合理调整:innodb_open_files  
  
innodb_open_files = 500  
# 限制Innodb能打开的表的数据,如果库里的表特别多的情况,请增加这个。这个值默认是300  
  
innodb_buffer_pool_size = 64M  
# InnoDB使用一个缓冲池来保存索引和原始数据, 不像MyISAM.  
# 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.  
# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%  
# 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.  
# 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,  
# 所以不要设置的太高.  
  
innodb_write_io_threads = 4  
innodb_read_io_threads = 4  
# innodb使用后台线程处理数据页上的读写 I/O(输入输出)请求,根据你的 CPU 核数来更改,默认是4  
# 注:这两个参数不支持动态改变,需要把该参数加入到my.cnf里,修改完后重启MySQL服务,允许值的范围从 1-64  
  
innodb_thread_concurrency = 0  
# 默认设置为 0,表示不限制并发数,这里推荐设置为0,更好去发挥CPU多核处理能力,提高并发量  
  
innodb_purge_threads = 1  
# InnoDB中的清除操作是一类定期回收无用数据的操作。在之前的几个版本中,清除操作是主线程的一部分,这意味着运行时它可能会堵塞其它的数据库操作。  
# 从MySQL5.5.X版本开始,该操作运行于独立的线程中,并支持更多的并发数。用户可通过设置innodb_purge_threads配置参数来选择清除操作是否使用单  
# 独线程,默认情况下参数设置为0(不使用单独线程),设置为 1 时表示使用单独的清除线程。建议为1  
  
innodb_flush_log_at_trx_commit = 2  
# 0:如果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作(执行是由mysql的master thread线程来执行的。  
# 主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交)默认的日志文件是ib_logfile0,ib_logfile1  
# 1:当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。  
# 2:如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。  
# 每次事务提交的时候将数据写入事务日志,而这里的写入仅是调用了文件系统的写入操作,而文件系统是有 缓存的,所以这个写入并不能保证数据已经写入到物理磁盘  
# 默认值1是为了保证完整的ACID。当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。  
# 设为0的话,mysqld进程崩溃的时候,就会丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。  
# 总结  
# 设为1当然是最安全的,但性能页是最差的(相对其他两个参数而言,但不是不能接受)。如果对数据一致性和完整性要求不高,完全可以设为2,如果只最求性能,例如高并发写的日志服务器,设为0来获得更高性能  
  
innodb_log_buffer_size = 2M  
# 此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据。MySQL开发人员建议设置为1-8M之间  
  
innodb_log_file_size = 32M  
# 此参数确定数据日志文件的大小,更大的设置可以提高性能,但也会增加恢复故障数据库所需的时间  
  
innodb_log_files_in_group = 3  
# 为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3  
  
innodb_max_dirty_pages_pct = 90  
# innodb主线程刷新缓存池中的数据,使脏数据比例小于90%  
  
innodb_lock_wait_timeout = 120   
# InnoDB事务在被回滚之前可以等待一个锁定的超时秒数。InnoDB在它自己的锁定表中自动检测事务死锁并且回滚事务。InnoDB用LOCK TABLES语句注意到锁定设置。默认值是50秒  
  
bulk_insert_buffer_size = 8M  
# 批量插入缓存大小, 这个参数是针对MyISAM存储引擎来说的。适用于在一次性插入100-1000+条记录时, 提高效率。默认值是8M。可以针对数据量的大小,翻倍增加。  
  
myisam_sort_buffer_size = 8M  
# MyISAM设置恢复表之时使用的缓冲区的尺寸,当在REPAIR TABLE或用CREATE INDEX创建索引或ALTER TABLE过程中排序 MyISAM索引分配的缓冲区  
  
myisam_max_sort_file_size = 10G  
# 如果临时文件会变得超过索引,不要使用快速排序索引方法来创建一个索引。注释:这个参数以字节的形式给出  
  
myisam_repair_threads = 1  
# 如果该值大于1,在Repair by sorting过程中并行创建MyISAM表索引(每个索引在自己的线程内)    
  
interactive_timeout = 28800  
# 服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。默认值:28800秒(8小时)  
  
wait_timeout = 28800  
# 服务器关闭非交互连接之前等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,  
# 取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义)。参数默认值:28800秒(8小时)  
# MySQL服务器所支持的最大连接数是有上限的,因为每个连接的建立都会消耗内存,因此我们希望客户端在连接到MySQL Server处理完相应的操作后,  
# 应该断开连接并释放占用的内存。如果你的MySQL Server有大量的闲置连接,他们不仅会白白消耗内存,而且如果连接一直在累加而不断开,  
# 最终肯定会达到MySQL Server的连接上限数,这会报'too many connections'的错误。对于wait_timeout的值设定,应该根据系统的运行情况来判断。  
# 在系统运行一段时间后,可以通过show processlist命令查看当前系统的连接状态,如果发现有大量的sleep状态的连接进程,则说明该参数设置的过大,  
# 可以进行适当的调整小些。要同时设置interactive_timeout和wait_timeout才会生效。  
  
[mysqldump]  
quick  
max_allowed_packet = 16M #服务器发送和接受的最大包长度  
  
[myisamchk]  
key_buffer_size = 8M  
sort_buffer_size = 8M  
read_buffer = 4M  
write_buffer = 4M

 

参考:

https://blog.csdn.net/dc_726/article/details/12340349

https://blog.csdn.net/dc_726/article/details/9336193

https://blog.linuxeye.cn/380.html

网络原理-家用路由器常识介绍

常见的家用路由器:如tp-link  以此举例

大白话:家用路由器 本质是   1个 三层路由器   +  1个 无线交换机。
三层路由器 一端连外网,另一端连 无线交换机。
无线交换机,一端连三层交换机,剩余端口 连 各种上网主机。

1、路由器的LAN口工作在第二层协议还是第三层协议上?

这个lan只是低端路由器,你说tp-link那种,简单说LAN是二次,WAN是三层,但一般说路由器,所有口都是三层的。

发送到网关的数据包转发出去是从LAN口出去的还是从WAN口出去的?
内部的数据就是LAN,上外网就是WAN,看情况的。

=======================================================

企业路由器通常有多个(两个以上)带有公网ip地址的端口 ,当路由器从内网收到一个数据包时, 他要做出决定 从哪个端口发送出去这个数据包到外网, 当他决定并且转发出去这个数据包时 他就完成了一次路由。
而对于家用路由器来说 ,它通常指带有一个公网ip【WAN口公网IP】(LAN口 是两层交换机 模式, 内网IP  互相 访问 是 mac 层的 交换,不算路由)。当内网数据从LAN口 进入路由器内部,从 WAN口 出去时,内网数据包进行了一次路由 到外网去。因为只有 一个 WAN口即一个公网IP,所以ip数据包 发送到外网是 一次没有选择的 路由选择。

2、家用路由器的路由协议

家用路由器是中低端路由器,采用的是静态路由协议。

3、家用路由器上面的wifi功能

wifi是 802.11 协议标准,包括 物理层和数据链路层,无线上网的wifi 信号最终会进入 路由器里面,这个时候,参考路由器的LAN端口。wifi 和LAN 是属于同一个网段 的,我这里推测  wifi 在 该子网内 互相访问时,只用到了路由器的 两层交换机功能。

当wifi 经WAN端口,访问外网时,才算经过了三层路由。【毕竟 子网 和 外网 是两个网段了,必须要在 三层上 修改IP地址,在外网看来,路由器的子网是透明的,只有一个路由器IP地址。】(所以难怪我在traceroute 内网 ip时,直连内网IP,中途没有经过路由,所以家用路由器的内网之间访问只需两层交换机就行)

windows命令行-文件-命令行输出重定向

无论是shell 还是 dos ,用法是一样的。

一共有4个输出到文件的命令,现以jar命令打war包举例说明:

命令 说明 举例
> 正常输出覆盖指定文件  jar -xvf my.war @select.txt  > output.txt
2> 正常输出尾部追加到指定文件  jar -xvf my.war @select.txt  2> output.txt
>> 异常输出覆盖指定文件  jar -xvf my.war @select.txt  >> error.txt
2>> 异常输出尾部追加到指定文件  jar -xvf my.war @select.txt  2>> error.txt

 

# 我这里用到 的 重定向 测试
netstat -r >/Users/cool/Desktop/test.txt

 

网络原理-计算机网络详解-mac表、arp表、路由表

大白话:记住内网 也可能包括了多个子网,所以用同一网段表示更精确。

MAC地址表(FDB表,2层):MAC地址——》交换机接口地址;
【只存在于交换机,用于帮助交换机指明mac帧应从哪个接口发出去】

补充说明:现在的家用路由器 ,是三层的,也有二层的交换机功能。


ARP缓存表(2.5层):IP地址——》MAC地址;
【存在于主机和路由器中,用于帮助主机或路由器,查询对应IP的mac地址,以便组建mac帧发送出去】

同一网段内通信,原mac地址和目标mac地址 与 原ip地址和目标ip地址一一对应 。不同网段通信,mac地址与ip地址不关联,mac地址从本处地址指向下一个接力地址这样可以区分,信息是从网关发来的,还是从另一个网段发来的。

从这里可以看出,arp缓存表只缓存本机网段内的ip与mac地址的关系。

arp请求是广播,因为不知道目标的mac地址,所以只能进行广播。广播只能在同网段内进行。这里广播的意思是,交换机收到广播请求时,会对其他剩余交换机端口全部转发【至于以前的hub时代,每台主机收到的mac帧,会查看是不是和自己的mac帧相同,或者收到了arp广播帧,这样会继续拆开数据包,检查IP数据,否则直接丢弃mac帧】

=======================================================

理论上可以设置两个不同的网段,然后用交换机连接。两个网段都可以指定一个(虚假的)网关,两个网段内的ip都设置静态ip。【这个时候,按照操作系统的逻辑,查路由表若目标IP属于同一网段内(不同网段只会先发给网关,mac帧目标地址是网关地址,但是目标IP不是网关IP而是真正的目标主机ip地址),查询arp缓存表,没有就发送arp请求,这个时候arp请求会经过交换机,交换机看到广播 mac帧 会 进行广播,这个时候两个网段都有arp请求了。但是arp响应还是在同一个网段内出现的。两个网段后面的mac帧信息,看交换机的mac帧–端口表,进行分发了。如果把交换机换成路由器,路由器收到arp广播,查看ip地址是不是自己的 ,是就发个arp响应,不是就丢弃,不会转发arp广播,因为同网段内有交换机 连接着其他主机,负责将arp广播到其他主机。唯一的问题是路由器收到这个错网段arp请求,应该是直接丢弃吧,应该不会出现路由器报警神马的,毕竟多一事不如少一事,路由器开发人员估计也是这个心态】【家用路由器就是个 三层路由器+无线交换机】《如果我用代码单独发一个arp包,里面的目标IP是另一个网段的,那么另一网段的目标主机能收到,但是发现不同网段的,这时候,不清楚操作系统的arp协议怎么解决,如果正常返回,操作系统中的arp缓存表也不会记录,如果想要通信,操作系统认为不属于同一网段,只会先发包给虚假的网关》

总结:从网络设计上讲,arp 广播请求 只针对 同一个网段内的目标主机。

=======================================================

arp应答是单播,因为知道请求者的mac地址。所以可以直接采用点对点的单播方式回答对方。

为何要缓存arp?因为如果不缓存,那么每次通信都需要广播,不仅费时且减小了广播消息对同网段的影响。 当然arp缓存也存在一定的有效时长。


路由表(FIB表,3层)【存在于主机和路由器上 ,就是用来决策和转发 IP数据包的表】

=======================================================

上网时信息过程

1、本机 开机联网  用dhcp获得 IP 或者 自己设置静态IP,获得本机IP后,会发一个??? 广播,询问 局域网内 是否 和本机 有相同 IP。

2、dns访问网络,其实就是访问 IP。

3、对   待访问IP  进行判断,

如果属于同一个子网,查询ARP缓存表,如果用就租金组建 mac帧,若没有,就发送一个 arp广播,询问IP持有者的 mac地址。等对方arp应答,发回mac地址。然后再组件 mac帧。

mac帧组建好后,就用物理信号,直接发给内网中的目标主机。内网中一般就只有交换机,不会再路由了,因为路由是三层了,是用来跨网段的。【路由表就是根据不同网段,来进行路由的,所以路由器就是用来跨网段的,如果不跨网段的话(记住,内网也可以划分成好多网段不同的子网,不同子网间就需要路由器连接),用二层交换机就够了 】

********************************************************

如果不属于一个子网,就查询网关的mac地址,如果有就组建mac帧,发给网关。如果没有网关的mac地址,就发arp查询,获得网关mac地址,然后组建mac帧。发给网关。

发给网关的mac帧,经过网关检查,发现mac帧中的IP地址不是自己的,于是查询路由表,重新组建mac帧,发给下一个目标。重新组建的mac帧,源mac地址为本网关mac地址,目标mac地址为下一个目标的mac地址。ip数据包里面的内容不变。

就这样,在不同的网段内不断转发,mac帧终于抵达了目标主机。

=======================================================

一、路由表

1、路由表概述

在计算机网络中,路由表或称路由择域信息库(RIB)是一个存储在路由器或者联网计算机中的电子表格(文件)或类数据库。

每个路由器中都有一个路由表和FIB(Forward Information Base)表:路由表用来决策路由,FIB用来转发分组。FIB强调的是作为转发的路由表,RIB是用来做路由管理的表。通常有了动态路由协议的参与才能理解这个问题。RIP、OSPF、BGP、ISIS都是动态路由协议,它们学习到的路由首先要通告给RIB表。RIB表把所有路由协议学习到的路由汇总到一起,经过优选,把优选结果的路由加入到FIB表,供转发使用。所以FIB是RIB的一个子集。

2、路由表中路由有三类:

直连路由:
(1)链路层协议发现的路由
非直连路由:
(1)静态路由
(2)动态路由协议发现的路由。

高档路由器可以运行动态路由选择协议,而中低档的不可以.只有运行了动态路由选择协议的路由器才可以自动生成和更新路由表.

一般的家用型路由器如tp-link都是运行的静态路由,静态路由是由管理员手工的逐条的输入的,不能自动适应网络的拓扑变化.静态路由里面有缺省路由条目,路由器收到的ip包,都会默认转发给上层路由器。

Pc电脑上的 路由表,是 静态路由。我做了一下测试:

(1)电脑上的网线网卡每换一个接入点,都会重新重新初始化PC路由表。

路由表上面的 0.0.0.0 网段,127网络, localhost网段 ,169.254网段【这个是电脑未联网时自己设置的所在网段】,224.0.0 组播网段,255.255.255.255【有限广播地址也称为本地广播地址】

广播地址分为两种:直接广播地址和有限广播地址  。TCP/IP协议规定32比特全为1的IP地址(255.255.255.255)用于本网广播。 在主机不知道本机所处的网络时(如主机的启动过程中),只能采用有限广播方式,通常由无盘工作站启动时使用,希望从网络IP地址服务器处获得一个IP地址。当广播地址包含一个有效的网络号和主机号,技术上就称为直接广播地址。

上面这些都是网络连接成功时,自动生成的路由表。其中 0.0.0.0是缺省路由,如果你是动态获取的IP地址,就是从DHCP服务器学来的;如果是手工静态分配的IP地址,则是静态分配来的;

(2)当别的内网计算机ping或访问本机时,本机路由表就会 添加 该内网计算机的路由。当本机访问别的内网主机或ping内网主机【即使ping的不存在】,本机也会将该内网主机添加到路由表中。当然,这些添加的路由只是暂时性的 ,重启或者切换网络都会路由记录都会被删除。本机自动添加的路由,只限于内网的计算机,外网的计算机路由,都不会添加到本机中。

下面 mac主机的路由表中:192.168.1.133 是另一台 内网主机。该内网的网段是192.168.1.128/25,网关是 192.168.1.129/32,本机IP是  192.168.1.131/32

3、路由表查看

Windows linux 通用: netstat -r  
Windows 上面 还可以用:route print

xp下的 路由表:

===========================================================================
Interface List
0x1 ........................... MS TCP Loopback interface
0x2 ...08 00 27 d7 b7 a9 ...... Intel(R) PRO/1000 T Server Adapter - 数据包计划程序微型端口
===========================================================================
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0         10.0.2.2       10.0.2.15	  10
         10.0.2.0    255.255.255.0        10.0.2.15       10.0.2.15	  10
        10.0.2.15  255.255.255.255        127.0.0.1       127.0.0.1	  10
   10.255.255.255  255.255.255.255        10.0.2.15       10.0.2.15	  10
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1	  1
        224.0.0.0        240.0.0.0        10.0.2.15       10.0.2.15	  10
  255.255.255.255  255.255.255.255        10.0.2.15       10.0.2.15	  1
Default Gateway:          10.0.2.2
===========================================================================
Persistent Routes:
  None

Route Table

mac下面的路由表:

Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.1.129      UGSc          512        0     en1
127                localhost          UCS             1        0     lo0
localhost          localhost          UH              2  1425190     lo0
169.254            link#5             UCS             1        0     en1
192.168.1.128/25   link#5             UCS             3        0     en1
192.168.1.129/32   link#5             UCS             2        0     en1
192.168.1.129      20:dc:e6:c1:ee:24  UHLWIir       513       25     en1    973
192.168.1.131/32   link#5             UCS             1        0     en1
192.168.1.133      5c:c3:7:4f:62:91   UHLWIi          1        9     en1    726
192.168.1.255      link#5             UHLWbI          1       12     en1
224.0.0            link#5             UmCS            2        0     en1
224.0.0.251        1:0:5e:0:0:fb      UHmLWI          1        0     en1
255.255.255.255/32 link#5             UCS             2        0     en1
broadcasthost      link#5             UHLWbI          1      139     en1

Internet6:
Destination        Gateway            Flags         Netif Expire
localhost          localhost          UHL             lo0
fe80::%lo0         fe80::1%lo0        UcI             lo0
fe80::1%lo0        link#1             UHLI            lo0
fe80::%en1         link#5             UCI             en1
cooldemacbook-pro. 38:c9:86:e7:7c:e   UHLI            lo0
fe80::%awdl0       link#9             UCI           awdl0
cooldemacbook-pro. 46:28:cb:55:19:75  UHLI            lo0
ff01::%lo0         localhost          UmCI            lo0
ff01::%en1         link#5             UmCI            en1
ff01::%awdl0       link#9             UmCI          awdl0
ff02::%lo0         localhost          UmCI            lo0
ff02::%en1         link#5             UmCI            en1
ff02::%awdl0       link#9             UmCI          awdl0

先百度了一下:mac 网络接口(Netif),的各种名字

lo0 = loopback
gif0 = Software Network Interface
stf0 = 6to4 tunnel interface
en0 = Ethernet 0
fw0 = Firewire
en1 = Ethernet 1
vmnet1 = Virtual Interface

补充:在运行ifconfig时,会看到en0 en1 en2 en3 en4 怎么这么多???

运行一下:networksetup -listallhardwareports

Hardware Port: Ethernet
Device: en0
Ethernet Address: xx:xx:xx:xx:xx:xx

Hardware Port: FireWire
Device: fw0
Ethernet Address: xx:xx:xx:xx:xx:xx:xx:xx

Hardware Port: Wi-Fi
Device: en1
Ethernet Address: xx:xx:xx:xx:xx:xx

Hardware Port: Bluetooth PAN
Device: en3
Ethernet Address: xx:xx:xx:xx:xx:xx

Hardware Port: Thunderbolt 1
Device: en2
Ethernet Address: xx:xx:xx:xx:xx:xx

Hardware Port: Thunderbolt Bridge
Device: bridge0
Ethernet Address: xx:xx:xx:xx:xx:xx

VLAN Configurations
===================

原来是Wi-Fi,蓝牙,thunderbolt

4、路由表讲解

举例:

(1)、通俗点说就是:接口指硬件网卡上的网线口,一个接口可以设置N个IP。

市面上有不止一个接口的网卡,2口、4口都有。

接口是你拥有的IP,因为允许一个网卡设置多个IP,所以接口的IP是数据包出去时的IP,网关是数据包从接口出去后,第一个访问的地址,不一定是路由器的…有可能是电信的服务器、有可能是公司的代理服务器,主要是看这个网关地址是哪里才能初步判断是什么东西。

(2)、网关是指数据从你接口出去先走哪里。比如就是你要出门,先要走你家大门一样,有些家庭不止一个大门的,所以要指定。

(3)、“在链路上”即指你电脑访问网络的链路中存在多个网关,VISTA以上的系统支持配置多个网关的多重网络。

(4)、mac上面的路由表:目标 指的是网段号;xp上面的路由表 ,目标指的是,网络地址,后面还跟着子网掩码,这样就可以计算出 网段号。

(5)、权值英语:Metrics),又称路由度量(routing metric),是电脑网络上,路由的参数之一,这个参数被用来决定某个特定路径是否应该被选择。权值主要在动态选径时使用。权值包含了被路由算法使用来决定哪一条路径较另一条路径好的所有数值。度量可能包括许多资讯,例如带宽、延迟、经过节点数、路径成本、负载、最大传输单元(MTU)、可靠性及传输成本等。路由表只储存最佳的可能路径,但连线状态或拓扑数据库可能储存其他相关的资讯。【来自维基百科】

路由会选择最低权值的闸道器路径(预设路径,default gateway)前进。如果权值为0,代表该路径的目的地,与本地端界面是连接在同一个网络上。如果权值大于零,该路径的目的地会被认为外部位址,必须透过外部闸道器才能抵达目的地。

5、路由表实例

如下图:详细介绍路由器的工作原理

1)HostA在网络层将来自上层的报文封装成IP数据包,其中源IP地址为自己,目标IP地址是HostB,HostA会用本机配置的24位子网掩码与目标地址进行“与”运算,得出目标地址与本机不是同一网段,因此发送HostB的数据包需要经过网关路由A的转发。

2)HostA通过ARP请求获取网关路由A的E0口的MAC地址,并在链路层将路由器E0接口的MAC地址封装成目标MAC地址,源MAC地址是自己。

3)路由器A从E0可接收到数据帧,把数据链路层的封装去掉,并检查路由表中是否有目标IP地址网段(即192.168.2.2的网段)相匹配的的项,根据路由表中记录到192.168.2.0网段的数据请发送给下一跳地址10.1.1.2,因此数据在路由器A的E1口重新封装,此时,源MAC地址是路由器A的E1接口的MAC地址,封装的目标MAC地址则是路由器2的E1接口的MAC地址。

4)路由B从E1口接收到数据帧,同样会把数据链路层的封装去掉,对目标IP地址进行检测,并与路由表进行匹配,此时发现目标地址的网段正好是自己E0口的直连网段,路由器B通过ARP广播,获知HostB的MAC地址,此时数据包在路由器B的E0接口再次封装,源MAC地址是路由器B的E0接口的MAC地址,目标MAC地址是HostB的MAC地址。封装完成后直接从路由器的E0接口发送给HostB。

5)此时HostB才会收到来自HostA发送的数据。

总结:路由表负责记录一个网络到另一个网络的路径,因此路由器是根据路由表工作的。


二、mac地址表

说到MAC地址表,就不得不说一下交换机的工作原理了,因为交换机是根据MAC地址表转发数据帧的。在交换机中有一张记录着局域网主机MAC地址与交换机接口的对应关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的。

交换机的工作原理

交换机在接收到数据帧以后,首先、会记录数据帧中的源MAC地址和对应的接口到MAC表中,接着、会检查自己的MAC表中是否有数据帧中目标MAC地址的信息,如果有则会根据MAC表中记录的对应接口将数据帧发送出去(也就是单播),如果没有,则会将该数据帧从非接受接口发送出去(也就是广播)。

如下图:详细讲解交换机传输数据帧的过程

 

1)主机A会将一个源MAC地址为自己,目标MAC地址为主机B的数据帧发送给交换机。

2)交换机收到此数据帧后,首先将数据帧中的源MAC地址和对应的接口(接口为f 0/1) 记录到MAC地址表中。

3)然后交换机会检查自己的MAC地址表中是否有数据帧中的目标MAC地址的信息,如果有,则从MAC地址表中记录的接口发送出去,如果没有,则会将此数据帧从非接收接口的所有接口发送出去(也就是除了f 0/1接口)。

4)这时,局域网的所有主机都会收到此数据帧,但是只有主机B收到此数据帧时会响应这个广播,并回应一个数据帧,此数据帧中包括主机B的MAC地址。

5)当交换机收到主机B回应的数据帧后,也会记录数据帧中的源MAC地址(也就是主机B的MAC地址),这时,再当主机A和主机B通信时,交换机根据MAC地址表中的记录,实现单播了。

如下图:当局域网存在多个交换机互联的时候,交换机的MAC地址表是怎么记录的呢?

 

1)主机A将一个源MAC地址为自己,目标MAC地址主机C的数据帧发送给交换机

2)交换机1收到此数据帧后,会学习源MAC地址,并检查MAC地址表,发现没有目标MAC地址的记录,则会将数据帧广播出去,主机B和交换机2都会收到此数据帧。

3)交换机2收到此数据帧后也会将数据帧中的源MAC地址和对应的接口记录到MAC地址表中,并检查自己的MAC地址表,发现没有目标MAC地址的记录,则会广播此数据帧。

4)主机C收到数据帧后,会响应这个数据帧,并回复一个源MAC地址为自己的数据帧,这时交换机1和交换机2都会将主机C的MAC地址记录到自己的MAC地址表中,并且以单播的形式将此数据帧发送给主机A。

5)这时,主机A和主机C通信就是一单播的形式传输数据帧了,主机B和主机C通信如上述过程一样,因此交换机2的MAC地址表中记录着主机A和主机B的MAC地址都对应接口f 0/1。

总结:从上面的两幅图可以看出,交换机具有动态学习源MAC地址的功能,并且交换机的一个接口可以对应多个MAC地址,但是一个MAC地址只能对应一个接口。

注意:交换机动态学习的MAC地址默认只有300S的有效期,如果300S内记录的MAC地址没有通信,则会删除此记录。


三、ARP缓存表

上面我们讲解了交换机的工作原理,知道交换机是通过MAC地址通信的,但是我们是如何获得目标主机的MAC地址呢?这时我们就需要使用ARP协议了,在每台主机中都有一张ARP表,它记录着主机的IP地址和MAC地址的对应关系。

ARP协议:ARP协议是工作在网络层的协议,它负责将IP地址解析为MAC地址。

如下图:详细讲解ARP的工作原理。

 

1)如果主机A想发送数据给主机B,主机A首先会检查自己的ARP缓存表,查看是否有主机B的IP地址和MAC地址的对应关系,如果有,则会将主机B的MAC地址作为源MAC地址封装到数据帧中。如果没有,主机A则会发送一个ARP请求信息,请求的目标IP地址是主机B的IP地址,目标MAC地址是MAC地址的广播帧(即FF-FF-FF-FF-FF-FF),源IP地址和MAC地址是主机A的IP地址和MAC地址。

2)当交换机接受到此数据帧之后,发现此数据帧是广播帧,因此,会将此数据帧从非接收的所有接口发送出去。

3)当主机B接受到此数据帧后,会校对IP地址是否是自己的,并将主机A的IP地址和MAC地址的对应关系记录到自己的ARP缓存表中,同时会发送一个ARP应答,其中包括自己的MAC地址。

4)主机A在收到这个回应的数据帧之后,在自己的ARP缓存表中记录主机B的IP地址和MAC地址的对应关系。而此时交换机已经学习到了主机A和主机B的MAC地址了。

 


参考:

mac表 arp表 路由表 http://blog.51cto.com/dengqi/1223132

en0 en1 问题      https://blog.csdn.net/yangziluomu?t=1

traceroute  原理及实现  https://www.jianshu.com/p/75a5822d0eec

Traceroute原理解析  https://www.jianshu.com/p/9465fa3abe47

Metrics 问题  https://en.wikipedia.org/wiki/Metrics_(networking)

网络原理-一张网卡设置两个IP的作用

一块网卡,设置两个IP的 作用

1、一个网卡设置两个或者多个IP地址,作用就是可以连接多个网段(就是可以访问多个网段),但前提是这些网段物理层是连接在一起。
2、举个例子:有两个LAN(局域网)通过交换机连接在一起,LAN1为192.168.0.0/24 网段
LAN2 为192.168.1.0/24网段,在没有三层设备的情况下LAN1与LAN2下的主机是不可以相互访问的,因为LAN1与LAN2的网络号分别为192.168.0.0、192.168.1.0,网络号不同即不在同一网段。虽然两个LAN通过交换机连接在一起了,但在没有三层设备时是无法进行通信的。但若是LAN1下的一台主机PC1设置两个IP地址如 192.168.0.100/24、192.168.1.100/24(不可与LAN2下的主机IP冲突) 则PC1就可以访问LAN2下的主机,因为此时PC1使用IP 192.168.1.100/24进行LAN2的访问。


设置双IP流程

首先打开“本地连接 属性”页

 

第二步,选择“Internet 协议版本4”点属性或双击它。打开“Internet 协议版本4 属性”页

 

第三步,设置其中一个IP段的IP地址、网关、DNS服务器地址,点“高级”,打开“高级TCP/IP设置”页。

 

第四步,点“添加”,输入另一个网段分配的IP地址,以及网关,如下图

 

第五步,点“确定”完成设置。

网络原理-网络拓扑之两条宽带叠加上网问题

一、宽带叠加概述

一直觉得上网,就需要一条宽带就行了。
偶尔想到,如果电脑同时接有线和无线宽带会怎么样?

当电脑连接两条宽带时,且两条宽带的公网ip不同。这时电脑上网会采用,有线宽带的IP。下载也是有线宽带。因为有线宽带的优先级比无线宽带高,我们需要修改有线网卡和无线网卡的跃点数,修改成一样【需要进入网络连接属性 /高级 TCP/IP 属性 修改 跃点数】。这样有线和无线宽带的优先级就一样了。平时上网只会用一条,但是用迅雷等多进程下载时,可以用两条宽带下载。

或者买一个双WAN口的 路由器或者 买两个路由器 且 组合成一个局域网,当电脑连接上路由器时,相当于两条宽带上网了。平时上网只用一条,多进程下载时可以用两条宽带。


无线和有线 同时连接时,电脑的路由表 (命令行 netstat -r) 可以看到 本机 无线网卡的 网段 和 有线网卡的网段 不一样,但是 电脑 同时可以访问 两个网段。【我测试时,无线连的是手机热点,有线连的是 路由器的 宽带】


二、两条宽带连PC操作

第一,右击右下角的网络图标,打开网络和共享中心,在弹出来的对话框中选择更改网络配置。

第二,在弹出来的对话框中可以找到我们现在使用的网络,右击击其中的一个网络适配器,选择属性。

第三,在弹出来的对话框中双击Internet 协议版本4,此项是用来设置我们当前使用的网络。

第四,此时会弹出常规选项卡,点击高级,在弹出来的对话框中我们去掉自动跃点的勾选,自己任意设置成任意数字,20 40都行,点击确定,这样我们就完成了一个网络适配器的更改。

 

第五,我们需要进行第二个网络适配器的更改,和上面的步骤一样,接口跃点数一定要设置成和第一个适配器的跃点数一样的数字,否则就不会网络叠加的成功。

此时,完成是配置的设置之后,我们就可以进行网络速度的测试了,很多软件均集成了这个功能,如360安全卫士,以前我的网速最大下载速度是500k左右,进行网络的叠加使用后就变成了1M下载,很强悍吧!

为什么非要跃点数设置成一样的呢?传输过程中需要经过多个网络,每个被经过的网络设备点叫做一个跃点,地址就是它的ip,跃点数是经过了多少个跃点的累加器,为了防止无用的数据包在网上流散。将跃点数设置成一样的数值,系统会认定为这是同一个网络,所以两个网络会合并为一个网络供我们使用。

=========================================================

命令行模式,查看 修改 效果前后 图

然后进入命令模式,输入route print 回车查看IP的跃点数,这做是为了寻找两者的差值以达到平衡
最后进入网卡修改跃点数

最后再route print一次两者跃点数相同就可以了,叠加成功,测速,下载,在线电影均有效。

三、双WAN口路由器或两个路由器操作

这里讲个三网叠加的 :

  1. 设置路由器C拨号,lan IP与路由器A、B同一网段PC端设置网关:顺序为路由器C、A、B,

  2. 看看速度,牛X,迅雷下载稳定3.2M/S

    遗憾的是手机端设置不了多个网关,不过10M宽带也够用了

 


参考:

双路由器实现宽带叠加 https://jingyan.baidu.com/article/1974b289a238d6f4b1f7743c.html
有线+无线叠加教程 http://tieba.baidu.com/p/2589595477
win8.1有线+无线同时上叠加上网设置 http://tieba.baidu.com/p/3309314007

网络原理-计算机网络详解-上网内部流程分析

首先,先读 计算机网络-整体认知把握 作为基础入门。

一、网络模型中各层的命名规范

如数据链路层(二层),一般称为帧(Frame),比如以太帧。
而 ATM(Asynchronous Transport Mode)一般称为信元(Cell)。
ATM 是欧洲人发明的,IP 是美国人发明的,两者竞争网络层的老大,最后 IP 胜出,成为当仁不让的网络层霸主。ATM 只好委身于 IP 的「淫威」之下,充当数据链路层协议。

那么网络层(三层)则使用包(Packet)的概念,比如 IP 包。

传输层有 TCP、UDP,TCP 称为报文段或段(Segment),而 UDP 则称为用户数据报或者UDP报文(Datagram)

应用层(七层)则一律使用应用层数据(Data)。

但往往也没有那么严格,经常有人用 TCP 包、UDP 包,也不会引起混淆,但还是希望各位同学能够专业化、规范化使用名称,养成一个良好习惯。


二、本地网创建过程

弄个路由器,弄个光纤猫,超五类网线,拨号上网就行了。

网线接好后,物理层就配好了,以太网速率自协商也完成了。
数据链路层也就是以太网帧。

1、设置内网IP

(1)配置路由器

用一根网线连路由器和pc,登录浏览器访问路由器的设置页面。然后修改网关IP和子网掩码,然后设置PPPOE,自动拨号上网。
比如
网关IP:192.168.1.129
子网掩码:255.255.255.128
那么路由器的网络地址为:192.168.1.128 广播地址为192.168.1.255

参看 网络层之子网划分与超网

(2)配置主机IP

配置主机IP有两种方法:

方法一:登录主机,设置静态IP。

方法二:DHCP,动态获取IP,需要在路由器里面开启DHCP服务。

2、DHCP协议详解

动态主机配置协议,英文 DHCP,是英文 Dynamic Host Configuration Protocol 的缩写,属于应用层协议,使用UDP协议工作。

DHCP运行分为四个基本过程,分别为请求IP租约、提供IP租约、选择IP租约和确认IP租约。客户在获得了一个IP地址以后,就可以发送一个ARP请求来避免由于DHCP服务器地址池重叠而引发的IP冲突。

1.DHCP发现(DISCOVER)—— 请求IP租约

电脑的操作系统安装了 TCP/IP 协议栈,这个协议栈其中包含一个 DHCP 客户端进程,这个客户端进程会广播一个发现服务器的报文,格式为 UDP 封装,目的端口号为 68,源端口号为 67;

大白话:DHCP客户机以广播方式(因为DHCP服务器的IP地址对于客户机来说是未知的)发送DHCPdiscover发现信息来寻找DHCP服务器,即向地址255.255.255.255发送特定的广播信息。网络上每一台安装了TCP/IP协议的主机都会接收到这种广播信息,但只有DHCP服务器才会做出响应。

客户也可以申请它使用的最后一个IP地址(在下面的例子里为192.168.1.100)。如果该客户所在的网络中此IP仍然可用,服务器就可以准许该申请。否则,就要看该服务器是授权的还是非授权的。授权服务器会拒绝请求,使得客户立刻申请一个新的IP。非授权服务器仅仅忽略掉请求,导致一个客户端请求的超时,于是客户端就会放弃此请求而去申请一个新的IP地址。

2.DHCP提供(OFFER)——提供IP租约

当DHCP服务器收到一个来自客户的IP租约请求时,它会提供一个IP租约。DHCP为客户保留一个IP地址,然后通过网络单播一个DHCPOFFER消息给客户。该消息包含客户的MAC地址、服务器提供的IP地址、子网掩码、租期以及提供IP的DHCP服务器的IP。并以单播方式发给客户端,目的端口号为 67,源端口号为 68 ;

服务器基于在CHADDR字段指定的客户硬件地址来检查配置。这里的服务器,192.168.1.1,将IP地址指定于YIADDR字段。,

3.DHCP请求(REQUEST)——选择IP租约

当客户PC收到一个IP租约提供时,它必须告诉所有其他的DHCP服务器它已经接受了一个租约提供。因此,该客户会发送一个DHCPREQUEST消息,其中包含提供租约的服务器的IP。当其他DHCP服务器收到了该消息后,它们会收回所有可能已提供给客户的租约。然后它们把曾经给客户保留的那个地址重新放回到可用地址池中,这样,它们就可以为其他计算机分配这个地址。任意数量的DHCP服务器都可以响应同一个IP租约请求,但是每一个客户网卡只能接受一个租约提供。

4.DHCP确认(Acknowledge,ACK)——确认IP租约

当DHCP服务器收到来自客户的REQUEST消息后,它就开始了配置过程的最后阶段。这个响应阶段以单播方式发送一个DHCPACK包给客户。这个包包含租期和客户可能请求的其他所有配置信息。
客户端接收到服务器的确认,会尝试将获得的 IP 参数配置到 TCP/IP 协议栈,还会尝试 ARP 广播请求自己的 IP 所对应的 MAC 地址,如果没有收到任何回复,说明这个 IP 地址在广播域里是唯一的,不会引起 IP 地址冲突,可以完成配置工作。

以上 DHCP 能够正常工作,有一个前提条件,那就是客户端与服务器在一个广播域内,一个广播域意味着一个网段,换句话说,一个网段需要一个 DHCP 服务器,这个对于拥有成百上千网段的大型网络来说,则需要成百上千的 DHCP 服务器,这显然不现实。

⬇️⬇️⬇️   其他过程补充如下:⬇️⬇️⬇️

5.重新登录 (DHCPrequest)
    以后DHCP客户机每次重新登录网络时,就不需要再发送DHCPdiscover发现信息了,而是直接发送包含前一次所
分配的IP地址的DHCPrequest请求信息。当DHCP服务器收到这一信息后,它会尝试让DHCP客户机继续使用原来的IP
地址,并回答一个DHCPack确认信息。如果此IP地址已无法再分配给原来的DHCP客户机使用时(比如此IP地址已分
配给其它DHCP客户机使用),则DHCP服务器给DHCP客户机回答一个DHCPnack否认信息。当原来的DHCP客户机收到此
DHCPnack否认信息后,它就必须重新发送DHCPdiscover发现信息来请求新的IP地址。

6.更新租约
    DHCP服务器向DHCP客户机出租的IP地址一般都有一个租借期限,期满后DHCP服务器便会收回出租的IP地址。如
果DHCP客户机要延长其IP租约,则必须更新其IP租约。DHCP客户机启动时和IP租约期限过一半时,DHCP客户机都会
自动向DHCP服务器发送更新其IP租约的信息。

7.获取配置参数(DHCPINFORM)
   如果客户通过别的手段获得了网络地址,它可以使用DHCPINFORM请求获得其它配置参数,服务器接收
到DHCPINFORM包,并建立一个DHCPACK消息,在其中包括一些合适客户的配置参数,只是不包括分配网络
地址,检查现有的绑定,在信息中不填充'yiaddr'字段或租用时间参数。服务器取得DHCPINFORM包内的
'ciaddr'地址,而返回DHCPACK包。

5、DHCP中继问题

以上 DHCP 能够正常工作,有一个前提条件,那就是客户端与服务器在一个广播域内【毕竟发的是255.255.255.255广播帧】,一个广播域意味着一个网段,换句话说,一个网段需要一个 DHCP 服务器,这个对于拥有成百上千网段的大型网络来说,则需要成百上千的 DHCP 服务器,这显然不现实。
有没有现实一点的解决方案呢?比如在一个企业网只需要一台 DHCP 服务器?
问题就来了,客户端与服务器不在一个网段,客户端如何通过广播发现服务器呢?要知道,广播报文无法跨越不同网段!
这个其实不难,只是需要一个角色来协助客户端与服务器发现彼此,这个角色名字叫 DHCP 中继代理。

* DHCP 中继代理(DHCP Relay Agent)

设想是这样的,每个网段都配置一个 DHCP 中继代理,DHCP 中继预先静态配置 DHCP 服务器的 IP 地址,DHCP 中继代理自然可以接收到本网段的客户端 DHCP 广播报文,然后将广播报文修改成单播报文,目的 IP 地址为 DHCP 服务器,源 IP 地址为代理自己的,然后单播发送给服务器,服务器的回复自然也是单播发给代理,代理再将服务器的回复以单播的方式发给客户端。
通俗地说,DHCP 中继代理就是让客户端与服务器相互发现彼此的中介结构。
下面我们举一个例子来说明。
小明打开电脑,运行于后台的 DHCP 客户端,帮助小明拿到了 10.1.1.2/24 这个地址,小美拿到了 10.1.1.3/24 这个地址,小丽却拿到了 10.1.2.2/24 这个地址。请问,小明、小美在一个网段,为何小丽却在另外一个网段,这是如何做到的?
谜底就是:小明、小美在一个广播域,在这个广播域里还有他们的网关,地址是 10.1.1.1/24,已经静态配置好了,网关充当 DHCP 中继代理的角色。除了以上介绍的将接收到的 DHCP 客户端,发现服务器的广播,转换成单播以外,还在 DHCP 报文内部填写了一个字段:「中继代理=10.1.1.1」,这样服务器就可以依据中继代理的地址,找到网段 10.1.1 地址池,然后找出空闲的地址就可以分配给小明、小美了。
同样的原理,小丽的 DHCP 广播被网关(10.1.2.1/24)接收,做了以下的工作:

* 广播修改成单播,源地址为网关的地址 10.1.2.1,目的地址为 DHCP 服务器地址 10.10.10.10
* 填写 DHCP 报文中继代理字段(Gateway),这里为 Gateway = 10.1.2.1
* 重新计算 UDP 校验和

然后发送出去,到达服务器,服务器依据中继代理字段,找到另外一个地址池 10.1.2,接着就可以从空闲地址里分一个 10.1.2.2 给小丽了,然后单播回复网关 10.1.2.1,剩下的步骤可以参考上面的标准流程的四个步骤  –>【请求IP租约、提供IP租约、选择IP租约和确认IP租约】
=====================================================

假设小明、小美、他们的网关、小丽、小丽的网关连在一个交换机上,也没有配置任何虚拟局域网(VLAN)来分隔广播域,以上五者工作在一个广播域,看看 DHCP 能否正常工作?
小明的电脑发一个 DHCP 广播,用于发现广播域里的服务器,广播域里没有 DHCP 服务器,以上五者都会接收小明的广播,小明的网关、小丽的网关自然也会接收到。
于是小明网关、小丽网关都会做中继代理,填上自己的 IP 地址,到达服务器,服务器会分配两个 IP 地址,一个是 10.1.1.x,另外一个是 10.1.2.x,那小明的电脑接受哪一个呢?当然谁先到用谁的!
小明的电脑使用哪个网段地址,完全取决于哪个网关反应快,动作麻利,这种不可预测性的解决方案,不能满足企业网的安全要求。
企业网对于一个员工使用哪一个网段有严格的要求,一个网段意味着不同的权限,所以一个员工要使用真正属于他的那个网段。

综上,企业网络管理,就会采用VLAN 用来隔离广播域,对自动获取IP进行 子网分段 和权限控制 。
=====================================================

6、DHCP与RARP的区别

RARP在功能上有点类似于DHCP协议,确切的说DHCP是BOOTP协议的升级,而BOOTP在某种意义上又是RARP协议的升级。BOOTP和RARP的区别在于RARP是在数据链路层实现的,而BOOTP实在应用层实现的,当然作为BOOTP的升级版DHCP也是在应用层实现的。
这种实现层面的差别也从RARP和BOOTP/DHCP的报文封装格式的差别上体现出来了,RARP直接封装在以太网帧中,协议类型置为0x0800以标识这个报文是ARP/RARP报文,BOOTP/DHCP报文是直接封装在UDP报文中,作为UDP的数据段出现的。
从功能上说,RARP只能实现简单的从MAC地址到IP地址的查询工作,RARP server上的MAC地址和IP地址是必须事先静态配置好的。但DHCP却可以实现除静态分配外的动态IP地址分配以及IP地址租期管理等等相对复杂的功能。

=========================================================

1)RARP可以满足主机IP地址配置的部分要求,但是不能完全满足
包括但不限于以下配置:
网络掩码,网关地址,静态路由,DNS服务器,以及私有的,公有的option功能。

2)RARP是二层协议,无法穿透子网,DHCP可以穿透子网。
好吧,那你会说有ARP代理,也可以辅助穿透子网,但是还是不好用。
因为:
ARP/RARP只能对地址进行识别,无法进行地址的统一规划和分配。
如果在一个子网内,需要对地址进行统一规划,分配和管理,以及租约,续租的管理。
必须要有一个服务器来集中管理。
因此有了bootp,有了DHCP。

我就知道还会有人说,为何不像DR,BDR路由器选举那样在用户计算机中产生一个集中管理的服务器,那是因为ARP/RARP是一个非常轻量级的协议,它设计的本意就不是这个。

另外,最重要的,用户计算机会当机,选举出来的服务器不稳定。

2.5)为何不修改ARP/RARP支持DHCP的特性?
DHCP的协议的工作本质,是动态主机配置协议,不仅仅包含IP地址配置。
TCP/IP网络的优点就是“分层”,协议各司其职。
ARP/RARP负责IP-MAC地址间的互相解析,DHCP负责管理IP层的配置。
因为,修改ARP/RARP支持DHCP,违反网络设计分层的理念。
应该去增强ARP/RARP,而不是去合并DHCP。
所以有了后来IPv6的ND。

3)既然如此为何IPv6会回归到ND(邻居发现协议),DHCPv6协同分配?
因为搞协议的人,逐渐发现,网络中有很多轻量级客户端,不需要进行统一管理,因此发明了ND,也就是增强版的ARP/RARP,它充分满足了没有DHCP服务器的情况下,在IPv6网络分配IP地址,路由前缀自动生成,快速上网的需求。


三、网络通信

大白话核心总结:

当生成完IP包,准备网络通信时,就需要判断目标主机和本机是否同网段。

如果本机和目标主机属于同一网段,

就查询本机的arp缓存表,如果存在目标主机mac地址,就直接读取,并生成两层的mac帧。如果本机的arp缓存表,没有目标主机的mac地址,那么就向本网段发送arp广播【arp请求广播只存在于本网段】,然后目标主机会发回arp单播应答给本机。这样目标主机就知道了,目标主机的mac地址了,并且将目标主机mac地址,放入本机arp缓存表。然后,本机三层ip包,封装成二层mac帧,发送给目标主机了。

如果本机和目标主机 是不同网段。

首先查找本机路由表,匹配和目标主机最接近的网段号。【依据本机路由表只记录本机网段的路由,所以匹配的结果是 发给默认网关】当决定IP数据包要发给默认网关时,此时检查本机arp缓存表,查询是否有网关的mac地址。如果有封装成mac帧,直接发给路由。如果没有记录网关mac地址,就发送arp广播请求,来获取网关mac地址。然后再将ip数据包组装成mac帧,发送给网关。

网关收到mac帧后,检查ip包和mac帧,发现mac地址与ip地址不匹配,不是真正发给自己的 ip包,于是查询路由表,找一个最长匹配的网络段的路由,重新组装mac帧发往下一个路由器(后面就是不断重复前面网关收到mac帧的操作发我下一个路由或目标主机)或者目标主机。【重新组装的mac帧,目标IP和源ip都不变,目标mac为下一跳的mac地址,源mac为当前网关】最终,经过几跳后,目标主机收到了mac帧。

1、访问相同网段

举例:ping 同一网段的主机。ping的协议介绍看这里

小明访问小美的电脑:比如 ping  10.1.1.3

(1)先判断 小美电脑 10.1.1.3  是否和 小明的电脑 10.1.1.2在同一个网段。

首先用小明的子网掩码  255.255.255.0 去 和 小明的IP 相与:计算出小明主机网络的网络号,即该网段的网络地址和广播地址【10.1.1.0   ,10.1.1.255】网络地址和广播地址直接的主机都属于同一网段。

然后对比目标地址:10.1.1.3  发现属于同网段。

(2)当生成三层IP包后,需要知道目标主机的mac 地址,来生成二层 mac帧。

首先查找本机的 arp缓存表,如果有,就直接读取,然后封装成mac帧,直接发给目标主机。

关于arp缓存表和路由表,查看这里

如果本机的arp缓存表,没有查到。就发送 arp广播请求【arp广播只存在于本网段】。

本机电脑用哪个网络接口发送arp广播请求呢?我们先了解一下本机路由表。

按照前面提到的子网划分博文,以上四条路由它们代表的网段号分别是:
127
10.1.1.2
10.1.1
0
用小美的网络号 10.1.1 与以上四条一一匹配,匹配到第三条,对应的接口为 Eth0。
于是,从接口 Eth0 发送 ARP 广播,ARP 广播在广播域里蔓延,小美的电脑也在同一个广播域可以接收到此 ARP 广播,广播请求 10.1.1.3 的硬件 MAC 地址,于是小美的电脑通过点对点单播 ARP 回复 10.1.1.2,自己的 MAC 是 MACxm,小明的电脑接收到此回复,将 10.1.1.3 / MACxm 保存在 ARP 缓存里,时间为 20—30 分钟不等,以备下次使用。

然后,本机三层ip包,封装成二层mac帧,发送给目标主机了。依照以上类似的步骤,Ping 的回包就到达本机的电脑,然后 Ping 程序软件显示,Ping 包被反弹回来,以及最大、最小、平均的来回延迟时间 RTT(Round Trip Time)。

2、访问不同网段

如果本机和目标主机 是不同网段。

首先查找本机路由表,匹配和目标主机最接近的网段号。【依据本机路由表只记录本机网段的路由,所以匹配的结果是 发给默认网关】当决定IP数据包要发给默认网关时,此时检查本机arp缓存表,查询是否有网关的mac地址。如果有封装成mac帧,直接发给路由。如果没有记录网关mac地址,就发送arp广播请求,来获取网关mac地址。然后再将ip数据包组装成mac帧,发送给网关。

网关收到mac帧后,检查ip包和mac帧,发现mac地址与ip地址不匹配,不是真正发给自己的 ip包,于是查询路由表,找一个最长匹配的网络段的路由,重新组装mac帧发往下一个路由器(后面就是不断重复前面网关收到mac帧的操作发我下一个路由或目标主机)或者目标主机。【重新组装的mac帧,目标IP和源ip都不变,目标mac为下一跳的mac地址,源mac为当前网关】最终,经过几跳后,目标主机收到了mac帧。

3、访问互联网

记录上网时,网络信息流处理过程

第一步:域名解析

互联网上网络层通信都是 IP数据包,所以小明的电脑与 百度服务器的通信也是 IP 包。既然是 IP 包,则需要 百度 服务器的 IP 地址,小明只告诉浏览器,自己想访问的服务器的域名是 HTTP://www.baidu.com,浏览器爽快地对小明说:没有关系,我会帮你解析出服务器的 IP 地址。

浏览器通知DNS程序(进程),解析www.baidu.com 的IP。

DNS域名解析过程如下:
1)DNS 进程先检查自己的程序缓存(Cache),如果有「www.baidu.com」所对应的 IP,则直接告诉浏览器。如果缓存没有找到,进入下一步;
2)检查本地 Host 文件,看看有没有,有则告诉浏览器。如果 Host 没有找到,进入下一步;
3)检查本地的 DNS 服务器配置,得到 DNS Server = 10.10.10.10,发个消息给它,让 DNS 服务器帮助查找。
此消息为 UDP 格式,目的 IP=10.10.10.10,小明电脑发现和自己不在一个网段,于是使用前面提到的不同网段的通信,将 IP 包发给 DNS Server = 10.10.10.10;
4)DNS Server (10.10.10.10)在自己的缓存里也没有发现,于是向互联网的上级DNS Server (8.8.8.8)发送协查请求;
DNS Server (8.8.8.8)发现了匹配项:HTTP://www.baidu.com 61.135.169.125,于是将协查结果返回给小明公司 DNS 服务器(10.10.10.10),然后再返回到小明电脑(10.1.1.2)DNS 进程。
DNS 进程气喘吁吁对浏览器说:大哥,这是您要的东西(HTTP://www.baidu.com 61.135.169.125)。

第二步:浏览器 HTTP 格式打包
浏览器将小明访问服务器 HTTP://www.baidu.com 的请求打包成 HTTP 格式,然后将打包好的 HTTP 告诉 TCP 进程(程序),同时告诉 TCP 进程的还有 HTTP://www.baidu.com 的 IP(61.135.169.125)。
TCP 进程属于低调、稳健的老司机,心想,如果将浏览器发来的 IP 地址 + HTTP 直接发给 IP 进程,最后会产生一个 IP 包,但最终这个 IP 包是死是活,自己却无法知道。也许 IP 包遭遇了线路硬件故障被丢弃,或网络路径拥堵被丢弃,或者服务器压根就没有开机,最终这个 IP 包消失得无踪无影。老司机犯愁地自言自语:那可怎么办才好呢?不远处 IP 进程听到了:臣妾也不知道啊!
最终老司机想出了一个办法,先不发 HTTP,先要确保自己的 IP 包(没有任何用户数据)可以到达服务器,并且服务器的 IP 包也可以返回,这样做的好处是:
一方面,可以保证双向的路径(路由)是畅通的,没有防火墙或访问列表的阻挡;
另一方面,如果 IP 包可以返回,说明服务器是正常工作的。这样老司机的所有担忧就都一一化解了。
这个方法是如何工作的呢?

第三步:HTTP 触发 TCP 进程三次握手连接
小明 TCP 司机:老大,有空吗?想和您唠唠,听到请回答!
服务器 TCP 老司机:小明,听得到,你能听到我吗?
小明 TCP 司机:听得到!
既然双方都可以听到对方(发送 IP 包到对方,并从对方接收 IP 包),那么就可以将小明的 HTTP,使用这个三次握手建立的 TCP 连接发送出去。但是,莫急,TCP 三次握手本身也会使用 IP 进程(程序)来完成发送,由于小明电脑与服务器不在一个网段,所以是三次不同网段的通信,上文详细阐述过整个过程,不再赘述。
在 IP 进程的眼里看,三次握手就是三个 IP 包(暂不考虑超时重传)的交互,还没有传输浏览器的 HTTP 之前,已经花费了来回三个 IP 包的代价。
此时,TCP 老司机是如何传输真正的 HTTP 的呢?

第四步:TCP 传输 HTTP
这个不难,只要使用 TCP 头将 HTTP 打包起来,包的格式为 TCP + HTTP,发给 IP 进程就好了。那么,在 IP 进程眼里,只是一个 IP 包而已,IP 包的格式为 IP + TCP + HTTP。那怎么知道对方是否接收到这个 IP 包呢?
TCP 确认收货机制
对方发一个确认,喊一嗓子:IP 包已收到,那么小明 TCP 进程就放心了,喃喃自语道:收到就好……
这里还有一个问题,小明 TCP 进程如何知道是哪个 IP 包被对方确认收货?
大家都有网购经验,卖家发货时,会在外包装上打上一个序列号,当买家确认收货时(确认产品序列号),这样卖家就知道某件产品已经安全无误地到达买家手中。
TCP 将每个字节标记机制
同样的原理可以用在 IP 网络通信中。技术来源于生活,而高于生活。为了保证可靠传输,用序列号标记一下 IP 包,标记在什么地方呢?
TCP 头有一个 Sequence Number,它就是序列号,就是为了实现这个目的的,比如小明的 TCP 进程要传输 1000 字节数据,初始序列号从 1 开始,那么 Sequence Number 设置为 1,然后 TCP 把这 1000 个字节打包,然后层层地封装、传输,并最终到达服务器 TCP 进程。
TCP 确认收货方法
服务器如何确认呢?
TCP 有一个字段是专门干这个的,确认收货号 Acknowledge Number,那么这里这个 Acknowledge Number 应该是多少呢?是 1001,为什么是 1001,难道这个和一千零一夜有关?
No!
1001 是告诉对方,从初始序列号 1 开始的 1000 个字节已经成功接收,准备好接收序列号从 1001 开始的数据了,这个应该很好理解吧?
小明 TCP 进程接收到此确认收货,就安心等待服务器将 HTTP://www.baidu.com 的页面发送过来了。
这个过程一个数据、一个确认收货,一共两个 IP 包。

第五步:服务器将自己的网页回传
服务器将自己的主页封装成 HTTP 格式,为了方便表达,假定主页只需要一个 TCP 就可以传输,此过程和第四步相似,即服务器 TCP 进程发给小明电脑一个 IP 包(包含网页),小明电脑回复一个收货确认(没有任何数据,只有 IP + TCP),那么一共两个 IP 包。
简而言之,TCP 的可靠传输机制:己方数据发送,对方确认,就这么简单。
第六步:释放 TCP 连接
小明浏览器将接收到的网页输出到屏幕上,任务就基本完成了。为什么说基本完成,而不说完全完成?因为还需要将之前建立的 TCP 连接断开,有同学会疑惑,为何要释放 TCP 连接?
因为数据已经传输完毕,TCP 连接依然活得好好的,但 TCP 连接会占用资源,比如会占用 TCP 端口资源、内存资源,既然不用了,就释放出来给有需要的应用程序使用。

* 通俗解释 TCP 关闭连接

TCP 连接可以看成两个水管,一个进水管,一个出水管。
从小明 TCP 进程来看,自己发数据用的是出水管,而接收服务器的数据使用进水管,释放连接意味着将两个水管都关闭。
如果小明没有数据要发给服务器,那可以放心地关闭出水管,但不能关闭进水管,因为进水管也许还有水,或者对方还需要继续运水过来,小明贸然关闭进水管不妥,可能会造成数据丢失。
所以进水管还是让对方来关闭比较恰当,因为对方会真正知道到底还有没有水要运输!
关闭 TCP 连接的步骤:
1)小明 TCP 进程:老大,我没有水要运了,准备关闭我的出水管了,收到请确认!
2)服务器 TCP 进程:小明,你的出水管里的水已经接收完毕,可以放心关闭,确认完毕!一旦小明接收到确认,出水管就完成关闭,不能再用出水管运水了。
此时,假设服务器也没有水要运给小明了,所以决定关闭服务器的出水管。(小明的进水管)
3)服务器 TCP 进程:小明,我也没有水要运了,准备关闭我的出水管了,收到请确认!
4)小明 TCP 进程:老大,你的出水管里的水已经接收完毕,可以放心关闭,确认完毕!
一旦服务器接收到确认,出水管(小明的进水管)就完成关闭,不能再用出水管运水了,服务器 TCP 进程释放资源。
小明 TCP 进程发出去的确认,自己无从知道是否对方已经接收到,除非对方超时重传关闭出水管的消息,小明启动一个定时器等待,如果超时以内没有接收到任何重传的消息,说明对方接收到自己的确认,那就彻底关闭 TCP 连接,释放所有资源;而如果接收到对方超时重传,自己再确认,然后再等待,直到最终确认对方接收到自己的确认。
这里不考虑超时重传,为了关闭 TCP 连接,一共使用了四个 IP 包。那么整个通信过程一共使用多少个 IP 包呢?
小明举起了手:车教练,一共是十一个!
车教练循循善诱:十一个是怎么来的?
小明:建立连接是三个,双向通信是四个,释放连接是四个。
车教练:回答完全正确,小明,考试合格,可以开车上路了……


参考:
https://blog.csdn.net/u013485792/article/details/50731538
http://www.qingpingshan.com/m/view.php?aid=215832

网络原理-网络拓扑之NAT

一、NAT含义


大白话:NAT就是将内网地址 翻译成外网地址。可以是一对一(静态转换),多对多(动态转换),多对一(端口多路复用)
NAT(Network Address Translation,网络地址转换)是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
这种方法需要在专用网连接到因特网的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址。这样,所有使用本地地址的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。

二、NAT分类


NAT的实现方式有三种,即静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。

1、静态转换Static Nat

静态转换是指将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一成不变的,某个私有IP地址只转换为某个公有IP地址。借助于静态转换,可以实现外部网络对内部网络中某些特定设备(如服务器)的访问。

2、动态转换Dynamic Nat

动态转换是指将内部网络的私有IP地址转换为公用IP地址时,IP地址是不确定的,是随机的,所有被授权访问上Internet的私有IP地址可随机转换为任何指定的合法IP地址。也就是说,只要指定哪些内部地址可以进行转换,以及用哪些合法地址作为外部地址时,就可以进行动态转换。动态转换可以使用多个合法外部地址集。当ISP提供的合法IP地址略少于网络内部的计算机数量时。可以采用动态转换的方式。

3、端口多路复用(Port address Translation)

 端口多路复用是指改变外出数据包的源端口并进行端口转换,即端口地址转换(PAT,Port Address Translation).采用端口多路复用方式。内部网络的所有主机均可共享一个合法外部IP地址实现对Internet的访问,从而可以最大限度地节约IP地址资源。同时,又可隐藏网络内部的所有主机,有效避免来自internet的攻击。因此,目前网络中应用最多的就是端口多路复用方式。

也被称为NAPT【(Network Address Port Translation),即网络端口地址转换】、“多对一”的NAT、地址超载(address overloading)。

三、ALG(Application Level Gateway)


即应用程序级网关技术:
在静态转换和动态转换中,内网中的一个ip都会被转换成外网的一个ip;所以数据流要改ip层和mac地址层。上面的网络层不需要修改。
在端口转换中,内网的一个应用请求,会被转换到外网的另一个端口作为请求。这样外网的一个ip地址,可以利用不同的端口完成来自不同的内网ip的请求。此时需要修改mac层,ip层和传输层。

但是一些应用层协议,在协议数据报文中包含了地址信息。为了使得这些应用也能透明地完成NAT转换,NAT使用一种称作ALG的技术,它能对这些应用程序在通信时所包含的地址信息也进行相应的NAT转换。例如:对于FTP协议的PORT/PASV命令、DNS协议的 “A” 和 “PTR” queries命令和部分ICMP消息类型等都需要相应的ALG来支持。
如果协议数据报文中不包含地址信息,则很容易利用传统的NAT技术来完成透明的地址转换功能,通常我们使用的如下应用就可以直接利用传统的NAT技术:HTTP、TELNET、FINGER、NTP、NFS、ARCHIE、RLOGIN、RSH、RCP等。

四、NAT超时介绍


因为 IP v4 的 IP 数量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。
大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。
长连接心跳间隔必须要小于NAT超时时间(aging-time),如果超过aging-time不做心跳,TCP长连接链路就会中断,Server就无法发送Push给手机,只能等到客户端下次心跳失败后,重建连接才能取到消息。


参考:
端口映射 和 nat 区别不是 太大
http://blog.sina.com.cn/s/blog_4988d99a0102wt97.html
NAT超时介绍
https://blog.csdn.net/hbjixieyuan/article/details/55048881
nat 教程 https://wenku.baidu.com/view/34b016673169a4517623a33e.html