Why https?

Why https?

  1. 保证用户信息的传输安全。包括用户名、密码、cookie、用户保存的服务器端信息等等
  2. 很大程度上免遭DNS劫持

Why not https?

  1. 更多的cpu资源的消耗
  2. 证书校验的时间消耗
  3. 证书校验可能因一些问题导致验证失败

java线程

java线程和操作系统线程之间的关系:

 

java线程管理是JVM的一部分,虽然大部分JVM直接映射java线程到底层系统线程,但是还是java的线程管理决定谁有机会运行

参考资料:

1. Java线程学习和总结:   http://blog.csdn.net/fantian830211/article/details/784597

tomcat建站

1. 安装tomcat

http://tomcat.apache.org/download-70.cgi

2. 安装eclipse的tomcat插件

http://www.eclipsetotale.com/tomcatPlugin.html

3. Servlet总结

http://www.iteye.com/topic/766418   Servlet的一些基本概念

http://www.iteye.com/topic/80171   从Servlet的各个部件、功能、框架方面介绍的深入浅出,需要看看

http://www.iteye.com/topic/952866     主要介绍了Servlet的生命周期

关于PHP中http请求的一个细节

缘起:

使用php的file_get_contents(…) 函数从广州发送一个http请求到北京,该请求的请求头和响应头如下:

现在,从广州到北京的一次数据的往返时间(就是ping的时间)为34ms,请求的执行时间为6ms; 因为请求头和相应头都非常小,分别一次tcp数据包就够,这样的话,一次http请求时间为: 34 + 34 + 6 = 74ms , 而实际却稳定在108ms左右,还有大约34ms不知去向

分析

根据这个丢失的时间长度来看,大概是多了一次数据的发送和接收; 通过tcpdump抓包发现如下现象:

file_get_contents(…)中实现的http请求,首先把请求行发送出去,收到请求行数据包的ack包后继续发送后续的请求头; 这样的话就凭空多出一次网络时间,其各种原因,有时间再看看PHP源码中为何如此实现吧。

测试了一下curl,没有这个问题。

IPv6的检测

看了一下如下脚本:

一次IPv6支持的检测需要5ms+的时间,成本是比较大的,但是,同一个进程中只检测一次,所以对于httpd进程来讲,这个是没有问题的

 

网络学习

实验目的:

1. 通过对链路层的抓包,了解网络结构及网关、路由的概念

实验场景:

10.49.4.65 和 10.49.4.64为同一个网段

实验步骤:

1. 在10.49.4.65上抓包

2. 从10.49.4.65上ping 10.4.4.64

 

抓包结果:

 

分析:

1.  第一个数据包,数据首先从10.49.4.65发送给网关; 因为路由表中有如下设置(大写G标志为经过网关):

(没有更精确匹配 10.49.4.64的路由了)

2. 10.49.4.64 上有如下路由配置(没有大写G,说明不需要经过网关):

(没有更精确匹配 10.49.4.65的路由了)

所以10.49.4.64可以直接回包给10.49.4.65; 但是10.49.4.64不知道10.49.4.65的mac地址是多少,于是先发了一个广播(第二个数据包,arp类型的),询问了一下; 10.49.4.65 回复了10.49.4.64的询问(第三个数据包,arp类型的),然后10.49.4.64就给出了icmp的响应包(第四个数据包)

总结

1. 添加一条路由,网关和接口至少指定一个

2. 只有同一个局域网下,才可以不经过网关(网关基本是有至少两块网卡的,用来连接不同的网络)

3. 指定网关的时候一般不需要同时指定接口

 

添加路由示例

1. 经过网关

2. 不经过网关

 

 

 

 

关于SO_DONTROUTE套接口选项的说明

转自:http://blog.csdn.net/sherlockhua/article/details/5365873

1 引子

在上一篇关于如何将套接口绑定到网络接口上的文章中,我曾经以为采用 SO_DONTROUTE 套接口选项能够实现和SO_BINDTODEVICE 选项同样的功能。但是实践证明不是这样。那么,其原因到底是为什么呢? SO_DONTROUTE 套接口选项真正的作用是什么呢?本文将对此予以解答。

2 问题求解

在 socket(7) 中对 SO_DONTROUTE 选项的说明如下:

SO_DONTROUTE

Don’t send via a gateway, only send to directly connected hosts.

The same effect can be achieved  by  setting  the  MSG_DONTROUTE

flag  on  a socket send(2) operation. Expects an integer boolean

flag.

这段话的核心意思是 SO_DONTROUTE 选项将导致数据包不经由网关发送,而是发往直接相连的主机。该套接口选项合法的值是整数形式的布尔标志值。

上述说明看起来似乎很明了,但是我 google 到的一些资料又说这个套接口选项将会绕过( bypass )路由表发送数据包,而且连 W. Richard Stevens 也是这样说的:“此选项规定发出的分组将旁路底层协议的正常路由机制。例如,对于 IPv4,分组被指向适当的本地接口,也就是目的地址的网络和子网部分所确定的本地接口。如果本地接口不能由目的地址确定(例如,目的主机不再一个点对点链路的另一端上,也不在一个共享网络上),则返回 ENETUNREACH 错误。……此选项经常由路由守护进程( routed 和 gated )用来旁路路由表(路由表不正确的情况下),强制一个分组从某个特定接口发出。” [UNIX 网络编程(第 1 卷),清华大学出版社,第 157 页 ] 。我不得不承认,正是这里的最后一句话,直接导致我认为可以通过 SO_DONTROUTE 套接口选项完成和 SO_BINDTODEVICE 同样的功能。但是实际上却并不是这样的。

为了解决这个问题,我编写了一个测试程序 udpsend2.c 。该程序要求要有三个参数,其中,第二个参数是数据包目的地的 IP 地址,第三个参数是一个开关,当为 on 时开启 SO_DONTROUTE 选项,当为 off 时关闭 SO_DONTROUTE 选项,默认情况下该选项是打开的。如果您理解该程序有困难,请先阅读《 UNIX 网络编程(第 1 卷)》。

 

如下编译程序:

[root@cyc src]# gcc -g -o udpsend2 udpsend2.c

3 对比测试

首先介绍一下初始时刻测试环境的设置情况,如下所示:

[root@cyc src]# uname -a

Linux cyc 2.4.20-8 #4 Sat Jan 20 19:42:09 CST 2007 i686 i686 i386 GNU/Linux

[root@cyc src]# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0D:87:EA:E3:AF

inet addr:202.115.26.224  Bcast:202.115.26.255  Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

RX packets:40016 errors:0 dropped:0 overruns:0 frame:0

TX packets:85327 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:100

RX bytes:3063524 (2.9 Mb)  TX bytes:36469606 (34.7 Mb)

Interrupt:11 Base address:0xc000

[root@cyc src]# route

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

202.115.26.0    *               255.255.255.0   U     0      0        0 eth0

default         202.115.26.1    0.0.0.0         UG    0      0        0 eth0

这里,作者所在的子网为 202.115.26.0/24 ,默认网关为 202.115.26.1 ,用于发送数据包的主机为 202.115.26.224 。用于接收数据的两台远端主机的 IP 地址分别为 202.115.26.193 和 202.112.14.184 。 202.115.26.193 与发送主机 202.115.26.224 位于同一网段内,通过交换机相连;而 202.112.14.184 则与发送主机 202.115.26.224 之间没有直接相连,中间通过多个路由器连接。连接示意图如下所示:

 

3.1 同网段的测试

首先测试的是 202.115.26.193 。路由表设置如下所示:

[root@cyc src]# route

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

202.115.26.0    *               255.255.255.0   U     0      0        0 eth0

default         202.115.26.1    0.0.0.0          UG    0      0        0 eth0

如下启动程序:

[root@cyc src]# ./udpsend2 202.115.26.193 on

send 512 to remote end…

程序报告发送了 512 字节的数据给 202.115.26.193 ,尽管对方并没有真正接收数据包。如我们所知, UDP 是无连接的,它只负责将数据包发出去,至于对方有没有接收到, UDP 是不管的。

接下来,去掉路由表中的默认路由:

[root@cyc src]# route del default

[root@cyc src]# route

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

202.115.26.0    *               255.255.255.0   U     0      0        0 eth0

再次运行 udpsend2 ,结果如下:

[root@cyc src]# ./udpsend2 202.115.26.193 on

send 512 to remote end…

结论:当目的主机与发送主机处于同一个网段内时,无论内核是否设置了默认路由,数据包总能发送给目的主机(尽管目的主机可能并没有在等待接收数据包)。但是,子网必须要在路由表中。比如,如果上面将子网 202.115.26.0 所在的路由表项也删除的话,就会得到网络不可达的结果,这一点是很容易理解的。

3.2 不同网段测试

其次来测试当发送主机与目的主机位于不同网段时的情况,此时的目的主机为 202.112.14.184 。发送主机上的路由表设置如下,并且发送主机能够 ping 通目的主机。这表明虽然 202.112.14.184 与 202.115.26.224 之间虽然并没有直接相连,但是能够通过路由器转发数据包来完成通信:

[root@cyc src]# route

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

202.115.26.0    *               255.255.255.0   U     0      0        0 eth0

default         202.115.26.1    0.0.0.0         UG    0      0        0 eth0

[root@cyc src]# ping 202.112.14.181

PING 202.112.14.181 (202.112.14.181) 56(84) bytes of data.

64 bytes from 202.112.14.181: icmp_seq=1 ttl=125 time=0.364 ms

运行程序 udpsend2 ,结果显示如下:

[root@cyc src]# ./udpsend2 202.112.14.181 on

sendto(): Network is unreachable

将默认路由(也即网关地址)从路由表中删除,再次运行程序:

[root@cyc src]# ./udpsend2 202.112.14.181 on

sendto(): Network is unreachable

结论:无论路由表中是否包含了默认路由(也即网关地址),当两主机之间没有直接相连时(即使能够通过中间路由器通信),设置了 SO_DONTROUTE 也将导致网络不可达错误。而网络不可达错误通常程序中有函数返回 ENETUNREACH 的结果。在本例中, ENETUNREACH 错误是由 sendto() 函数引发的。

4 总的结论

根据上面的测试结果,我认为: SO_DONTROUTE 套接口选项并没有完全绕过路由表,而只是绕过了路由表中网关(或者说默认路由)所在的表项。因此, Linux 的 socket(7) 中的说明是正确并且无歧义的,而《 UNIX 网络编程(第 1卷)》中的说法则带有一定的歧义性,容易给人造成误解。当然,这也可能是译者翻译不准确的缘故。总的来讲,当目的主机与发送方直接相连时,可以通过 SO_DONTROUTE 来实现从指定的网络接口发出数据包。但是,当接受者与发送方并没有直接相连时,就不能这样做了。而需要考虑通过 SO_BINDTODEVICE 选项或者 RAW 套接口或者 PACKET 套接口来实现。(注: RAW 套接口能实现网络层的直接数据访问,而 PACKET 套接口则能实现链路层的直接数据访问)。

 

相关参考: http://blog.csdn.net/namelcx/article/details/8063543