TCP/IP

1. OSI与TCP/IP各层的结构与功能,都有哪些协议。

OSI七层与TCP/IP五层网络架构详解

OSI和TCP/IP是很基础但又非常重要的网络基础知识,理解得透彻对运维工程师来说非常有帮助。今天偶又复习了一下:

(1)OSI七层模型

OSI中的层 功能 TCP/IP协议族

应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet

表示层 数据格式化,代码转换,数据加密 没有协议

会话层 解除或建立与别的接点的联系 没有协议

传输层 提供端对端的接口 TCP,UDP

网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP

数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU

物理层 以二进制数据形式在物理媒体上传输数据 ISO2110,IEEE802,IEEE802.2

(2)TCP/IP五层模型的协议

应用层

传输层

网络层

数据链路层

物理层

物理层:中继器、集线器、还有我们通常说的双绞线也工作在物理层

数据链路层:网桥(现已很少使用)、以太网交换机(二层交换机)、网卡(其实网卡是一半工作在物理层、一半工作在数据链路层)

网络层:路由器、三层交换机

传输层:四层交换机、也有工作在四层的路由器

二、TCP/UDP协议

TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP则不为IP提供可靠性、 流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。TCP支持的应用协议主要 有:Telnet、FTP、SMTP等;UDP支持的应用层协议主要有:NFS(网络文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系 统)、TFTP(通用文件传输协议)等.

TCP/IP协议与低层的数据链路层和物理层无关,这也是TCP/IP的重要特点

三、OSI的基本概念

OSI是Open System Interconnect的缩写,意为开放式系统互联。

OSI七层参考模型的各个层次的划分遵循下列原则:

1、同一层中的各网络节点都有相同的层次结构,具有同样的功能。

2、同一节点内相邻层之间通过接口(可以是逻辑接口)进行通信。

3、七层结构中的每一层使用下一层提供的服务,并且向其上层提供服务。

4、不同节点的同等层按照协议实现对等层之间的通信。

第一层:物理层(PhysicalLayer),

规定通信设备的机械的、电气的、功能的和过程的特性,用以建立、维护和拆除物理链路连接。具体地讲,机械 特性规定了网络连接时所需接插件的规格尺寸、引脚数量和排列情况等;电气特性规定了在物理连接上传输bit流时线路上信号电平的大小、阻抗匹配、传输速率 距离限制等;功能特性是指对各个信号先分配确切的信号含义,即定义了DTE和DCE之间各个线路的功能;规程特性定义了利用信号线进行bit流传输的一组 操作规程,是指在物理连接的建立、维护、交换信息是,DTE和DCE双放在各电路上的动作系列。在这一层,数据的单位称为比特(bit)。属于物理层定义的典型规范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。

第二层:数据链路层(DataLinkLayer):

在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路,通过差错控制提供数据帧(Frame)在信道上无差错的传输,并进行各电路上的动作系列。数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)。数据链路层协议的代表包括:SDLC、HDLC、PPP、STP、帧中继等。

第三层是网络层

在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息- -源站点和目的站点地址的网络地址。如 果你在谈论一个IP地址,那么你是在处理第3层的问题,这是“数据包”问题,而不是第2层的“帧”。IP是第3层问题的一部分,此外还有一些路由协议和地 址解析协议(ARP)。有关路由的一切事情都在这第3层处理。地址解析和路由是3层的重要目的。网络层还可以实现拥塞控制、网际互连等功能。在这一层,数据的单位称为数据包(packet)。网络层协议的代表包括:IP、IPX、RIP、OSPF等。

第 四层是处理信息的传输层

第4层的数据单元也称作数据包(packets)。但是,当你谈论TCP等具体的协议时又有特殊的叫法,TCP的数据单元称为段 (segments)而UDP协议的数据单元称为“数据报(datagrams)”。这个层负责获取全部信息,因此,它必须跟踪数据单元碎片、乱序到达的 数据包和其它在传输过程中可能发生的危险。第4层为上层提供端到端(最终用户到最终用户)的透明的、可靠的数据传输服务。所为透明的传输是指在通信过程中 传输层对上层屏蔽了通信传输系统的具体细节。传输层协议的代表包括:TCP、UDP、SPX等。

第五层是会话层

这一层也可以称为会晤层或对话层,在会话层及以上的高层次中,数据传送的单位不再另外命名,而是统称为报文。会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验证用户登录便是由会话层完成的。

第六层是表示层

这一层主要解决拥护信息的语法表示问题。它将欲交换的数据从适合于某一用户的抽象语法,转换为适合于OSI系统内部使用的传送语法。即提供格式化的表示和转换数据服务。数据的压缩和解压缩, 加密和解密等工作都由表示层负责。

第七层应用层

应用层为操作系统或网络应用程序提供访问网络服务的接口。应用层协议的代表包括:Telnet、FTP、HTTP、SNMP等。

除了层的数量之外,开放式系统互联(OSI)模型与TCP/IP协议有什么区别?

开放式系统互联模型是一个参考标准,解释协议相互之间应该如何相互作用。TCP/IP协议是美国国防部发明的,是让互联网成为了目前这个样子的标准之一。开放式系统互联模型中没有清楚地描绘TCP/IP协议,但是在解释TCP/IP协议时很容易想到开放式系统互联模型。两者的主要区别如下:

TCP/IP协议中的应用层处理开放式系统互联模型中的第五层、第六层和第七层的功能。

TCP/IP协议中的传输层并不能总是保证在传输层可靠地传输数据包,而开放式系统互联模型可以做到。TCP/IP协议还提供一项名为UDP(用户数据报协议)的选择。UDP不能保证可靠的数据包传输。

TCP/UDP协议

TCP(Transmission Control Protocol)和UDP(User DatagramProtocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。

TCP支持的应用协议主要有:Telnet、FTP、SMTP等;UDP支持的应用层协议主要有:NFS(网络文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。

TCP/IP协议与低层的数据链路层和物理层无关,这也是TCP/IP的重要特点。

OSI是Open System Interconnect的缩写,意为开放式系统互联。

2. TCP与UDP的区别。

TCP协议与UDP协议的区别
    首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信!
TCP/IP协议是一个协议簇。里面包括很多协议的。UDP只是其中的一个。之所以命名为TCP/IP协议,因为TCP,IP协议是两个很重要的协议,就用他两命名了。
TCP/IP协议集包括应用层,传输层,网络层,网络访问层。
其中应用层包括:
超文本传输协议(HTTP):万维网的基本协议.   
文件传输(TFTP简单文件传输协议):   
远程登录(Telnet),提供远程访问其它主机功能,它允许用户登录     
internet主机,并在这台主机上执行命令.   
网络管理(SNMP简单网络管理协议),该协议提供了监控网络设备的方法,以及配置管理,统计信息收集,性能管理及安全管理等.   
域名系统(DNS),该系统用于在internet中将域名及其公共广播的网络节点转换成IP地址. 
其次网络层包括:   
Internet协议(IP)    
Internet控制信息协议(ICMP)   
地址解析协议(ARP)   
反向地址解析协议(RARP)  
最后说网络访问层:网络访问层又称作主机到网络层(host-to-network).网络访问层的功能包括IP地址与物理地址硬件的映射,以及将IP封装成帧.基于不同硬件类型的网络接口,网络访问层定义了和物理介质的连接.
当然我这里说得不够完善,TCP/IP协议本来就是一门学问,每一个分支都是一个很复杂的流程,但我相信每位学习软件开发的同学都有必要去仔细了解一番。
下面我着重讲解一下TCP协议和UDP协议的区别。
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,只简单的描述下这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
详细点说就是:(文章部分转载http://zhangjiangxing-gmail-com.iteye.com,主要是这个人讲解得很到位,的确很容易使人理解!)
TCP三次握手过程
1 主机A通过向主机B发送一个含有同步序列号的标志位的数据段给主机B ,向主机B请求建立连接,通过这个数据段,
主机A告诉主机B两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我.
2 主机B收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:
我已经收到你的请求了,你可以传输数据了;你要用哪佧序列号作为起始数据段来回应我
3 主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B的数据段:"我已收到回复,我现在要开始传输实际数据了
这样3次握手就完成了,主机A和主机B就可以传输数据了.
3次握手的特点
没有应用层的数据
SYN这个标志位只有在TCP建产连接时才会被置1
握手完成后SYN标志位被置0

TCP建立连接要进行3次握手,而断开连接要进行4次

1 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求
2  主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1
3 由B端再提出反方向的关闭请求,将FIN置1
4 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.
由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式,大大提高了数据通信的可靠性,使发送数据端
和接收端在数据正式传输前就有了交互,为数据正式传输打下了可靠的基础
名词解释
ACK  TCP报头的控制位之一,对数据进行确认.确认由目的端发出,用它来告诉发送端这个序列号之前的数据段
都收到了.比如,确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性.
SYN  同步序列号,TCP建立连接时将这个位置1
FIN  发送端完成发送任务位,当TCP完成数据传输需要断开时,提出断开连接的一方将这位置1
TCP的包头结构:
源端口 16位
目标端口 16位
序列号 32位
回应序号 32位
TCP头长度 4位
reserved 6位
控制代码 6位
窗口大小 16位
偏移量 16位
校验和 16位
选项  32位(可选)
这样我们得出了TCP包头的最小长度,为20字节。

UDP(User Data Protocol,用户数据报协议)
(1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
(2)由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
(3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
(4)吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。
UDP的包头结构:
源端口 16位
目的端口 16位
长度 16位
校验和 16位

小结TCP与UDP的区别:
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。

3. TCP报文结构。

TCP(Transmission Control Protocol)传输控制协议是一种面向连接的、可靠的、基于字节流的传输层协议

TCP报文格式:

源端口号(2字节):

d5 df(54751)

目的端口号(2字节):

22 b8(8888)

TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接

序号(4字节):

37 59 56 75

用来标识TCP发端向TCP收端发送的数据字节流

确认序号(4字节):

由于该报文为SYN报文,ACK标志为0,故没有确认序号(ACK标志为1时确认序号才有效)

一旦连接建立,该值将始终发送(同ACK标志)

首部长度(4位):报文头长度(单位:位)/32

1000(转化为10进制为8,8*32/8 = 32,该报文报头长度为32个字节)

存在该字段是因为TCP报头中任选字段长度可变

报头不包含任何任选字段则长度为20字节;4位所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节

标志位(12位):

0000 00010010

Reserved

000~ ~~~~~~~~

 ECN(Explicit Congetsion Notification)

~~~0 ~~~~~~~~ = N /NS / Nonce Sum:有效排除潜在的ECN滥用,RFC 3540

~~~~ 0~~~~~~~ = C /CWR(Congestion Window Reduced):拥塞窗口减少标志

~~~~ ~0~~~~~~ = E /ECE / ECN-Echo:ECE / ECN标志

Control Bits

~~~~ ~~0~~~~~ =U / Urgent:紧急指针有效性标志

~~~~ ~~~1~~~~ =A / Acknowledgment:确认序号有效性标志。一旦一个连接建立起来,该标志总被置为1(除了SYN标志为1的报文,其它所有报文的该标志总为1)

~~~~ ~~~~0~~~ = P /Push:Push标志(接收方应尽快将报文段提交至应用层)

~~~~ ~~~~~0~~ = R /Reset:重置连接标志

~~~~ ~~~~~~1~ = S /Syn:同步序号标志

~~~~ ~~~~~~~0 = F /Fin:传输数据结束标志

窗口大小(2字节):TCP流量控制通过连接的每一端声明窗口大小进行控制(接收缓冲区大小)

20 00(00100000 00000000)= 8192

由于2字节能够表示的最大正整数为65535,故窗口最大值为65535

检验和(2字节):检验和覆盖整个TCP报文段;强制字段,由发送端计算存储,由接收端进行验证

2e 2f

紧急指针(2字节):当Urgent标志置1时,紧急指针才有效

00 00

任选字段(0 - 40字节):

每个选项格式如下:

选项类型

选项总长度

选项内容

说明如下:

说明

占用字节数

选项类型

1

0-255

选项总长度

1

length

选项内容

length - 2

可选选项如下:

Kind

Length

Description

References

0

1

End of option list.

RFC 793

1

1

No operation.

RFC 793

2

4

MSS, Maximum Segment Size.

RFC 793

3

3

WSOPT, Window scale factor.

RFC 1323

4

2

SACK permitted.

RFC 2018

5

Variable.

SACK.

RFC 2018, RFC 2883

6

6

Echo. (obsolete).

RFC 1072

7

6

Echo reply. (obsolete).

RFC 1072

8

10

TSOPT, Timestamp.

RFC 1323

9

2

Partial Order Connection permitted.

RFC 1693

10

3

Partial Order service profile.

RFC 1693

11

6

CC, Connection Count.

RFC 1644

12

6

CC.NEW

RFC 1644

13

6

CC.ECHO

RFC 1644

14

3

Alternate checksum request.

RFC 1146

15

Variable.

Alternate checksum data.

RFC 1146

16

Skeeter.

17

Bubba.

18

3

Trailer Checksum Option.

19

18

MD5 signature.

RFC 2385

20

SCPS Capabilities.

21

Selective Negative Acknowledgements.

22

Record Boundaries.

23

Corruption experienced.

24

SNAP.

25

26

TCP Compression Filter.

27

8

Quick-Start Response.

RFC 4782

28

4

User Timeout.

RFC 5482

29

TCP-AO, TCP Authentication Option.

RFC 5925

30

MPTCP

31 - 252

253

RFC3692-style Experiment 1.

RFC 4727

254

RFC3692-style Experiment 2.

RFC 4727

255

{02 04 05 b4} {01}{03 03 08} {01} {01} {04 02}

MSS + No operation +WSOPT + No operation + No operation + SACK permitted

一、报文结构

二、字段

  • 源、目标端口(source and destination port)

占16位,0-65535,用于区分进程

  • 顺序号(sequence number)

占32位,指定本报文数据相对于数据起始位置的字节偏移量,用于重组

  • 确认号(acknowledgement number)

占32位,指出源主机期望收到的下一报文的起始编号,用于确认

  • 头部长度(header length)

占4位,20-60,由于头部长度可变

  • 标志位(flag)

占6位,URG:紧急指针有效;ACK:确认号有效;PSH:接收方应尽快将此报文交给应用层;RST:重建连接;SYN:新建连接;FIN:结束一个连接

  • 窗口大小(window size)

占16位,指定本机期望一次接收的字节数,用于流量控制

  • 校验和(checksum)

占16位,伪头+TCP头+数据,用于校验

  • 紧急指针(urgent pointer)

占16位,和顺序号相加表示紧急数据的最后一字节序号

  • 选项(options)

可变,可包括MSS,"窗口扩大因子",时间戳等,用于两端的变量协商

三、结构体

/usr/include/netinet/tcp.h

struct tcphdr

{

u_int16_t th_sport;         /* sourceport */

u_int16_t th_dport;         /*destination port */

tcp_seq th_seq;             /*sequence number */

tcp_seq th_ack;             /*acknowledgement number */

#  if __BYTE_ORDER == __LITTLE_ENDIAN

u_int8_t th_x2:4;           /*(unused) */

u_int8_t th_off:4;          /* dataoffset */

#  endif

#  if __BYTE_ORDER == __BIG_ENDIAN

u_int8_t th_off:4;          /* dataoffset */

u_int8_t th_x2:4;           /*(unused) */

#  endif

u_int8_t th_flags;

#  define TH_FIN        0x01

#  define TH_SYN        0x02

#  define TH_RST        0x04

#  define TH_PUSH       0x08

#  define TH_ACK        0x10

#  define TH_URG        0x20

u_int16_t th_win;           /*window */

u_int16_t th_sum;           /*checksum */

u_int16_t th_urp;           /*urgent pointer */

};

四、报文

  SharedDocuments Edited By Zhaotao

4. TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的作用。

http://blog.csdn.net/whuslei/article/details/6667471/

http://www.cnblogs.com/yuxingfirst/archive/2013/06/30/3163400.html

说起TCP,我们一般都需要知道发起一个tcp连接和终止一个tcp连接是所发生的事情,下边,我将跟大家介绍下tcp的三次握手及四次挥手的过程。

TCP三路握手

(1)服务器必须准备好接受外来的连接。这通常在调用socket,bind,listen这三个函数来完成,我们称之为被动打开(passive open)。

(2)客户通过调用socket,connect发起主动打开(active open)。这导致客户tcp发送一个SYN(同步)分节,它告诉服务器客户将在待建立的tcp连接中发送数据的初始序列号。通常SYN分节不携带数据,其所在的IP数据报只包含有一个IP首部、一个TCP首部及可能有的TCP选项。

(3)服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户SYN的ACK(确认)。

(4)客户必须确认服务器的SYN。

这种交换至少需要三个分组,因此称之为TCP的三路握手,如图1:

图1

TCP四路挥手

TCP建立一个连接需要3个分节,而终止一个连接一般需要4个分节,所以一般也称为四路挥手。

(1)某个应用进程首先调用close,我们称为该端执行主动关闭(active close),该端的tcp于是发送一个FIN分节,表示数据发送完毕。

(2)接收到这个FIN的对端执行被动关闭(passive close)。这个FIN由tcp确认。它的接受也作为一个文件结束符传递给接收端的应用进程(放在已排队等候该应用进程接受的任何其他数据之后),因为FIN的接受意味着接收端应用进程在相应的连接上再无额外数据可接受。

(3)一段时间后,接受到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的tcp也发送一个FIN分节。

注:为什么是需要一段时候后,我的理解是由于接收到的fin分节作为一个文件结束符放在已排队等候应用进程接受的所有数据之后,而应用进程调用read读取数据得等它把这个文件描述符之前的所有数据读取完后,才能读取到该文件描述符,此时read返回0, 所以此时应用进程才知道对端已关闭了套接字,进而它也调用close关闭i套接字。

(4)接受这个最终FIN的原发送端tcp(即执行主动关闭的那一端)确认这个FIN。

如图2展示的这些分组:

图2

TCP连接发起和终止时套接字的状态

tcp为一个连接定义了11中状态,并且tcp规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态。下边我们通过图3来展示tcp连接的分组交换情况及tcp套接字的状态:

图3

一旦建立一个连接,客户就构造一个请求并发送给服务器。服务器处理该请求并发送一个应答,需要注意的是,服务器对客户请求的确认是伴随器应答发送的。这种做法称为捎带(piggybacking),它通常在服务器处理请求并产生应答的时间少于200ms时发生。如果服务器耗用更长时间,如1s,那么我们将看到先是确认后是应答。

接下来展示了终止tcp连接时交换的4个分节,从图中我们可以看到,发送一个单分节请求和接受一个单分节的应答,使用tcp至少需要8个分节的开销;如果改用udp,那么只需要交换两个分组:一个承载请求,一个承载应答。不过从tcp切换到udp也失去了tcp提供给应用进程的全部可靠性,迫使应用进程来做可靠性处理。

建立TCP需要三次握手才能建立,而断开连接则需要四次握手。整个过程如下图所示:

先来看看如何建立连接的。

首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。

那如何断开连接呢?简单的过程如下:

【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

整个过程Client端所经历的状态如下:

而Server端所经历的过程如下:转载请注明:blog.csdn.net/whuslei

【注意】 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

5. TCP拥塞控制。

6. TCP滑动窗口与回退N针协议。

滑动窗口机制

(1).窗口机制
    滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。不同的滑动窗口协议窗口大小一般不同。发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。下面举一个例子(假设发送窗口尺寸为2,接收窗口尺寸为1):

分析:①初始态,发送方没有帧发出,发送窗口前后沿相重合。接收方0号窗口打开,等待接收0号帧;②发送方打开0号窗口,表示已发出0帧但尚确认返回信息。此时接收窗口状态不变;③发送方打开0、1号窗口,表示0、1号帧均在等待确认之列。至此,发送方打开的窗口数已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧。接收窗口此时状态仍未变;④接收方已收到0号帧,0号窗口关闭,1号窗口打开,表示准备接收1号帧。此时发送窗口状态不变;⑤发送方收到接收方发来的0号帧确认返回信息,关闭0号窗口,表示从重发表中删除0号帧。此时接收窗口状态仍不变;⑥发送方继续发送2号帧,2号窗口打开,表示2号帧也纳入待确认之列。至此,发送方打开的窗口又已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧,此时接收窗口状态仍不变;⑦接收方已收到1号帧,1号窗口关闭,2号窗口打开,表示准备接收2号帧。此时发送窗口状态不变;⑧发送方收到接收方发来的1号帧收毕的确认信息,关闭1号窗口,表示从重发表中删除1号帧。此时接收窗口状态仍不变。

若从滑动窗口的观点来统一看待1比特滑动窗口、后退n及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已。1比特滑动窗口协议:发送窗口=1,接收窗口=1;后退n协议:发窗口>1,接收窗口>1;选择重传协议:发送窗口>1,接收窗口>1。

(2).1比特滑动窗口协议

当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停等协议(stop-and-wait)。该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。由于接收方需要判断接收到的帧是新发的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。其发送方和接收方运行的流程图如图所示。

(3).后退n协议

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议。后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。且发送方在每发送完一个数据帧时都要设置超时定时器。只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。如:当发送方发送了N个帧后,若发现该N帧的前一个帧在计时器超时后仍未返回其确认信息,则该帧被判为出错或丢失,此时发送方就不得不重新发送出错帧及其后的N帧。

从这里不难看出,后退n协议一方面因连续发送数据帧而提高了效率,但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。由此可见,若传输信道的传输质量很差因而误码率较大时,连续测协议不一定优于停止等待协议。此协议中的发送窗口的大小为k,接收窗口仍是1。

(4).选择重传协议

在后退n协议中,接收方若发现错误帧就不再接收后续的帧,即使是正确到达的帧,这显然是一种浪费。另一种效率更高的策略是当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层。这种方法称为选择重发(SELECTICE REPEAT),其工作过程如图所示。显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间。

滑动窗口协议

仍然考虑链路的延迟与带宽的乘积为8 K B,帧尺寸为1 K B的情形。让发送方在收到第一帧的A C K的同时准备发送第九帧。允许我们这样做的算法称为滑动窗口( sliding window),时间线如图2 - 2 1所示。

1. 滑动窗口算法


滑动窗口算法工作过程如下。首先,发送方为每1帧赋一个序号(sequence number),记作S e q N u m。现在,让我们忽略S e q N u m是由有限大小的头部字段实现的事实,而假设它能无限增大。发送方维护3个变量:发送窗口大小(send window size),记作S W S,给出发送方能够发

送但未确认的帧数的上界; L A R表示最近收到的确认帧( last acknowledgement re c e i v ed)的序号;L F S表示最近发送的帧(last frame sent)的序号,发送方还维持如下的不变式:

LAR-LFR≤RWS

当一个确认到达时,发送方向右移动L A R,从而允许发送方发送另一帧。同时,发送方为所发的每个帧设置一个定时器,如果定时器在A C K到达之前超时,则重发此帧。注意:发送方必须存储最多S W S个帧,因为在它们得到确认之前必须准备重发。

接收方维护下面3个变量:接收窗口大小(receive window size),记为RW S,给出接收方所能接收的无序帧数目的上界; L A F表示可接收帧(l a rgestacceptable frame)的序号;L F R表示最近收到的帧(last frame re ce i v e d)的序号。接收方也维持如下不变式:

LFS-LAR≤SWS 

当一个具有顺序号S e q N u m的帧到达时,接收方采取如下行动:如果S e q N u m≤L F R或S e q N u m > L A F,那么帧不在接收窗口内,于是被丢弃;如果L F R<Se q N u m≤L A F,那么帧在接收窗口内,于是被接收。现在接收方需要决定是否发送一个A C K。设S e q N u m To A C K表示未被确认帧的最大序号,则序号小于或等于S e q N u m To Ac k的帧都已收到。即使已经收到更高序号的分组,接收方仍确认S e q N u m To A c k的接收。这种确认被称为是累积的(c u m u l a t i v e)。然后它设置L F R = S e q Nu m To A c k,并调整L A F = L F R + RW S。例如,假设L F R= 5(即,上次接收方发送的A C K是为了确认顺序号5的),并且RWS = 4。这意味着L A F = 9。如果帧7和8到达,则存储它们,因为它们在接收窗口内。然而并不需要发送A C K,因为帧6还没有到达。帧7和8被称为是错序到达的。(从技术上讲,接收方可以在帧7和8到达时重发帧5的A C K。)如果帧6当时到达了(或许它在第一次丢失后又重发从而晚到,或许它只是被延迟了),接收方确认帧8,L F R置为8,L A F置为1 2。如果实际上帧6丢失了,则出现发送方超时,重发帧6。我们看到,当发生超时时,传输数据量减少,这是因为发送方在帧6确认之前不能向前移动窗口。这意味着分组丢失时,此方案将不再保证管道满载。注意:分组丢失时间越长,这个问题越严重。
注意,在这个例子中,接收方可以在帧7刚一到达时就为帧6发送一个认帧N A K(negative acknowledgment)。然而,由于发送方的超时机制足以发现这种情况,发送N A K反而为发送方增加了复杂性,因此不必这样做。正如我们已提到的,当帧7和8到达时为帧5发送一个额外的A C K是合理的;在某些情况下,发送方可以使用重复的A C K作为一个帧丢失的线索。这两种方法都允许早期的分组丢失检测,有助于改进性能。
关于这个方案的另一个变种是使用选择确认(selective acknowledgements)。即,接收方能够准确地确认那些已收到的帧,而不只是确认按顺序收到最高序号的帧。因此,在上例中,接收方能够确认帧7、8的接收。如果给发送方更多的信息,就能使其较容易地保持管道满载,但增加了实现的复杂性。

发送窗口大小是根据一段给定时间内链路上有多少待确认的帧来选择的;对于一个给定的延迟与带宽的乘积,S W S是容易计算的。另一方面,接收方可以将RW S设置为任何想要的值。通常的两种设置是:RW S= 1,表示接收方不存储任何错序到达的帧; RW S=S W S,表示接收方能够缓存发送方传输的任何帧。由于错序到达的帧的数目不可能超过S W S个,所以设置RWS >S W S没有意义。

2. 有限顺序号和滑动窗口


现在我们再来讨论算法中做过的一个简化,即假设序号是可以无限增大的。当然,实际上是在一个有限的头部字段中说明一个帧的序号。例如,一个3比特字段意味着有8个可用序号0 ~ 7。因此序号必须可重用,或者说序号能回绕。这就带来了一个问题:要能够区别同一序号的不同次发送实例,这意味着可用序号的数目必须大于所允许的待确认帧的数目。例如,停止等待算法允许一次有1个待确认帧,并有2个不同的序号。
假设序号空间中的序号数比待确认的帧数大1,即S W S ≤ M A a xS e q N u m -1 ,其中M a x Seq N u m 是可用序号数。这就够了吗?答案取决于RW S 。如果RW S = 1,那么MaxSeqNum≥SWS+1是足够了。如果RW S等于S W S,那么有一个只比发送窗口尺寸大1的M a x S e q N u m是不够的。为看清这一点,考虑有8个序号0 ~ 7的情况,并且S W S = RW S = 7。假设发送方传输帧0 ~ 6,并且接收方成功接收,但A C K丢失。接收方现在希望接收帧7,0 ~ 5,但发送方超时,然后发送帧0 ~ 6。不幸的是,接收方期待的是第二次的帧0 ~ 5,得到的却是第一次的帧0 ~ 5。这正是我们想避免的情况。
结果是,当RW S = S W S时,发送窗口的大小不能大于可用序号数的一半,或更准确地说,SWS<(Maxseqnum+1)/2直观地,这说明滑动窗口协议是在序号空间的两半之间变换,就像停止等待协议的序号是在0和1之间变换一样。唯一的区别是,它在序号空间的两半之间连续滑动而不是离散的变换。
注意,这条规则是特别针对RW S = S W S的。我们把确定适用于RW S和S W S的任意值的更一般的规则留做一个练习。还要注意,窗口的大小和序号空间之间的关系依赖于一个很明显以至于容易被忽略的假设,即帧在传输中不重新排序。这在直连的点到点链路上不能发生,因为在传输过程中一个帧不可能赶上另一个帧。然而,我们将在第5章看到用在一个不同环境中的滑动窗口算法,并且需要设计另一条规则。

3. 滑动窗口的实现


下面的例程说明我们如何实现滑动窗口算法的发送和接收的两个方面。该例程取自一个正在使用的协议,称为滑动窗口协议S W P(Sliding Window Pro t o c o l)。为了不涉及协议图中的邻近协议,我们用H L P(高层协议)表示S W P上层的协议,用L I N K(链路层协议)表示S W P下层的协议。我们先定义一对数据结构。首先,帧头部非常简单:它包含一个序号( S e q N u m)和一个确认号( A c k N u m)。它还包含一个标志( F l a g s)字段,表明帧是一个A C K帧还是携带数据的帧。

其次,滑动窗口算法的状态有如下结构。对于协议发送方,该状态包括如上所述的变量L A R和L F S,以及一个存放已发出但尚未确认的帧的队列( s e n d Q)。发送方状态还包含一个计数信号量( counting semaphore),称为s e n d Wi n d o w N o t F u l l。下面我们将会看到如何使用它,但一般来说,信号量是一个支持s e m Wa i t和s e m S i g n a l操作的同步原语。每次调用S e m S i g n al,信号量加1,每次调用S e m Wa i t,信号量减1。如果信号量减小,导致它的值小于0,那么调用进程阻塞(挂起)。一旦执行了足够的s e m S i g n a l操作而使信号量的值增大到大于0,在调用s e m Wa i t的过程中阻塞的进程就允许被恢复。
对于协议的接收方,如前所述,该状态包含变量L F R ,加上一个存放已收到的错序帧的队列(r e c v Q)。最后,虽然未显示,发送方和接收方的滑动窗口的大小分别由常量S W S和RW S表示。

S W P的发送方是由s e n d S W P过程实现的。这个例程很简单。首先, s e m Wa i t使这个进程在一个信号量上阻塞,直到它可以发另一帧。一旦允许继续, s e n d S W P设置帧头部中的顺序号,将此帧的拷贝存储在发送队列( s e n d Q)中,调度一个超时事件以便处理帧未被确认的情况,并将帧发给低层协议。

值得注意的一个细节是刚好在调用m s g A d d H dr之前调用s t o r e _ s w p _ h d r。该例程将存有S W P头部的C语言结构( s t a t e -> h d r)转化为能够安全放在消息前面的字节串( h b u f)。该例程(未给出)必须将头部中的每一个整数字段转化为网络字节顺序,并且去掉编译程序加入C语言结构中的任意填充。7 . 1节将详细讨论字节顺序的问题,但现在,假设该例程将多字整数中最高有效位放在最高地址字节就足够了。
这个例程的另一个复杂性是使用s e m Wa i t 和s e n dW i n d ow N o t F u l l 信号量。S e n dWi n d o w N o t F u l l被初始化为发送方滑动窗口的大小S W S(未给出这一初始化)。发送方每传输一帧, s e m Wa i t操作将这个数减1,如果减小到0,则阻塞发送方进程。每收到一个A C K,在d e l i v e r SW P中调用s e m S i g n a l操作(见下面)将此数加1,从而激活正在等待的发送方进程。

在继续介绍S W P的接收方之前,需要调整一个看上去不一致的地方。一方面,我们说过,高层协议通过调用s e n d操作来请求低层协议的服务,所以我们就希望通过S W P发送消息的协议能够调用s e n d(S W P, p a c k e t)。另一方面,用来实现S W P的发送操作的过程叫做s e n d S W P,并且它的第一个参数是一个状态变量( S w p S t a t e)。结果怎样呢?答案是,操作系统提供了粘结代码将对s e n d的一般调用转化为对s e n d S W P的特定协议调用的粘结代码。这个粘结代码将s e n d的第一个参数(协议变量S W P)映射为一个指向s e n d S W P的函数指针和一个指向S W P工作时所需的协议状态的指针。我们之所以通过一般函数调用使高层协议间接调用特定协议函数,是因为我们想限制高层协议中对低层协议编码的信息量。这使得将来能够比较容易地改变协议图的配置。现在来看d e l i v e r操作的S W P的特定协议实现,它在过程d e l i v e r SW P中实现。这个例程实际上处理两种不同类型的输入消息:本结点已发出帧的A C K和到达这个结点的数据帧。在某种意义上,这个例程的ACK部分是与send SWP中所给算法的发送方相对应的。通过检验头部的F l a g s字段可以确定输入的消息是ACK还是一个数据帧。注意,这种特殊的实现不支持数据帧中捎带A C K。当输入帧是一个ACK时,delive rSWP仅仅在发送队列(send Q)中找到与此ACK相应的位置(slot),取消超时事件,并且释放保存在那一位置的帧。由于A C K可能是累积的,所以这项工作实际上是在一个循环中进行的。对于这种情况值得注意的另一个问题是子例程swp In Wind o w的调用。这个子例程在下面给出,它确保被确认帧的序号是在发送方当前希望收到的A C K的范围之内。
当输入帧包含数据时, d e l i v e r S W P首先调用m s g S t r i pH d r和l o a d _ s w p _ h d r以便从帧中提取头部。例程l o a d _ s w p_ h d r对应着前面讨论的s t o r e _ s w p _ h d r,它将一个字节串转化为容纳S W P头部的C语言数据结构。然后d e l i v e r SW P调用s w p I n Wi n d o w以确保帧序号在期望的序号范围内。如果是这样,例程在已收到的连续的帧的集合上循环,并通过调用d e l i v e r HL P例程将它们传给上层协议。它也要向发送方发送累积的A C K,但却是通过在接收队列上循环来实现的(它没有使用本节前面给出的s e q N u m To Ac k变量)。

最后,s w p I n Window是一个简单的子例程,它检查一个给定的序号是否落在某个最大和最小顺序号之间。

4. 帧顺序和流量控制


滑动窗口协议可能是计算机网络中最著名的算法。然而,关于该算法易产生混淆的是,它可以有三个不同的功能,第一个功能是本节的重点,即在不可靠链路上可靠地传输帧。(一般来说,该算法被用于在一个不可靠的网络上可靠地传输消息。)这是该算法的核心功能。

滑动窗口算法的第二个功能是用于保持帧的传输顺序。这在接收方比较容易实现,因为每个帧有一个序号,接收方要保证已经向上层协议传递了所有序号比当前帧小的帧,才向上传送该当前帧。即,接收方缓存了(即没有传送)错序的帧。本节描述的滑动窗口算法确实保持了帧的顺序,尽管我们可以想象一个变异,即接收方没有等待更早传送的帧都到达就将帧传给下一个协议。我们可以提出的一个问题是:我们是否确实需要滑动窗口协议来保持帧的顺序,或者,这样的功能在链路层是否是不必要的。不幸的是,我们还没有看到足够多的网络体系结构来回答这个问题我们首先需要理解的是,点到点链路序列如何由交换机连接而形成一条端到端的路径。
滑动窗口算法的第三个功能是,它有时支持流量控制(f l o w c o n t ro l),它是一种接收方能够控制发送方使其降低速度的反馈机制。这种机制用于抑制发送方发送速度过快,即抑制传输比接收方所能处理的更多的数据。这通常通过扩展滑动窗口协议完成,使接收方不仅确认收到的帧,而且通知发送方它还可接收多少帧。可接收的帧数对应着接收方空闲的缓冲区数。在按序传递的情况下,在将流量控制并入滑动窗口协议之前,我们应该确信流量控制在链路层是必要的。
尚未讨论的一个重要概念是系统设计原理,我们称其为相关性分离(separation of concerns)。即,你必须小心区别有时交织在一种机制中的不同功能,并且你必须确定每一个功能是必要的,而且是被最有效的方式支持的。在这种特定的情况下,可靠传输、按序传输和流量控制有时组合在一个滑动窗口协议里,我们应该问问自己,在链路层这样做是否正确。带着这样的疑问,我们将在第3章(说明X. 2 5网如何用它实现跳到跳的流量控制)和第5章(描述T C P如何用它实现可靠的字节流信道)重新考虑滑动窗口算法。

7. Http的报文结构。

引用
学习Web开发不好好学习HTTP报文,将会“打拳不练功,到老一场空”,你花在犯迷糊上的时间比你沉下心来学习HTTP的时间肯定会多很多。

HTTP请求报文解剖

HTTP请求报文由3部分组成( 请求行+请求头+请求体 ):

下面是一个实际的请求报文:

①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。

②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL,③是协议名称及版本号。

④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。

⑤是报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1&param2=value2”的方式传递请求参数。

对照上面的请求报文,我们把它进一步分解,你可以看到一幅更详细的结构图:

引用
HttpWatch是强大的网页数据分析工具,安装后将集成到Internet Explorer工具栏中。它不用代理服务器或一些复杂的网络监控工具,就能抓取请求及响应的完整信息,包括Cookies、消息头、查询参数、响应报文等,是Web应用开发人员的必备工具。

HTTP请求报文头属性

报文头属性是什么东西呢?我们不妨以一个小故事来说明吧。

引用
快到中午了,张三丰不想去食堂吃饭,于是打电话叫外卖:老板,我要一份[鱼香肉丝],要12:30之前给我送过来哦,我在江湖湖公司研发部,叫张三丰。

这里,你要[鱼香肉丝]相当于HTTP报文体,而“12:30之前送过来”,你叫“张三丰”等信息就相当于HTTP的报文头。它们是一些附属信息,帮忙你和饭店老板顺利完成这次交易。

请求HTTP报文和响应HTTP报文都拥有若干个报文关属性,它们是为协助客户端及服务端交易的一些附属信息。

常见的HTTP请求报文头属性

Accept

请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。

如下报文头相当于告诉服务端,俺客户端能够接受的响应类型仅为纯文本数据啊,你丫别发其它什么图片啊,视频啊过来,那样我会歇菜的~~~:

Java代码  
  1. Accept:text/plain

Accept属性的值可以为一个或多个MIME类型的值,关于MIME类型,大家请参考: http://en.wikipedia.org/wiki/MIME_type

Cookie

客户端的Cookie就是通过这个报文头属性传给服务端的哦!如下所示:

Java代码  
  1. Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C

服务端是怎么知道客户端的多个请求是隶属于一个Session呢?注意到后台的那个jsessionid=5F4771183629C9834F8382E23BE13C4C木有?原来就是通过HTTP请求报文头的Cookie属性的jsessionid的值关联起来的!(当然也可以通过重写URL的方式将会话ID附带在每个URL的后面哦)。

Referer

表示这个请求是从哪个URL过来的,假如你通过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是http://www.google.com。

引用

唐僧到了西天. 
如来问:侬是不是从东土大唐来啊? 
唐僧:厉害!你咋知道的! 
如来:呵呵,我偷看了你的Referer... 

很多貌似神奇的网页监控软件(如著名的  我要啦 ),只要在你的网页上放上一段JavaScript,就可以帮你监控流量,全国访问客户的分布情况等报表和图表,其原理就是通过这个Referer及其它一些HTTP报文头工作的。

Cache-Control

对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。

如以下设置,相当于让服务端将对应请求返回的响应内容不要在客户端缓存:

Java代码  
  1. Cache-Control: no-cache

其它请求报文头属性

参见: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

如何访问请求报文头

由于请求报文头是客户端发过来的,服务端当然只能读取了,以下是HttpServletRequest一些用于读取请求报文头的API:

Java代码  
  1. //获取请求报文中的属性名称
  2. java.util.Enumeration<java.lang.String>   getHeaderNames();
  3. //获取指定名称的报文头属性的值
  4. java.lang.String getHeader(java.lang.String name)

由于一些请求报文头属性“太著名”了,因此HttpServletRequest为它们提供了VIP的API:

Java代码  
  1. //获取报文头中的Cookie(读取Cookie的报文头属性)
  2. Cookie[]   getCookies() ;
  3. //获取客户端本地化信息(读取 Accept-Language 的报文头属性)
  4. java.util.Locale    getLocale()
  5. //获取请求报文体的长度(读取Content-Length的报文头属性)
  6. int getContentLength();

HttpServletRequest可以通过

Java代码  
  1. HttpSession getSession()

获取请求所关联的HttpSession,其内部的机理是通过读取请求报文头中Cookie属性的JSESSIONID的值,在服务端的一个会话Map中,根据这个JSESSIONID获取对应的HttpSession的对象。(这样,你就不会觉得HttpSession很神秘了吧,你自己也可以做一个类似的会话管理   )

HTTP响应报文解剖

响应报文结构

HTTP的响应报文也由三部分组成( 响应行+响应头+响应体 ):

以下是一个实际的HTTP响应报文:

①报文协议及版本; 
②状态码及状态描述; 
③响应报文头,也是由多个属性组成; 
④响应报文体,即我们真正要的“干货”。

响应状态码

和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。

HTTP的响应状态码由5段组成:

  • 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
  • 2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
  • 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
  • 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
  • 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。

以下是几个常见的状态码:

200 OK

你最希望看到的,即处理成功!

303 See Other

我把你redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。

引用
悟空:师傅给个桃吧,走了一天了  
唐僧:我哪有桃啊!去王母娘娘那找吧

304 Not Modified

告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!

404 Not Found

你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。

500 Internal Server Error

看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!

其它的状态码参见: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

有些响应码,Web应用服务器会自动给生成。你可以通过HttpServletResponse的API设置状态码:

Java代码  
  1. //设置状态码,状态码在HttpServletResponse中通过一系列的常量预定义了,如SC_ACCEPTED,SC_OK
  2. void    setStatus(int sc)

常见的HTTP响应报文头属性

Cache-Control

响应输出到客户端后,服务端通过该报文头属告诉客户端如何控制响应内容的缓存。

下面,的设置让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取 (当然,这个功能是靠客户端实现的,服务端只是通过这个属性提示客户端“应该这么做”,做不做,还是决定于客户端,如果是自己宣称支持HTTP的客户端,则就应该这样实现) 。

Java代码  
  1. Cache-Control: max-age=3600

ETag

一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。

关于ETag的说明,你可以参见: http://en.wikipedia.org/wiki/HTTP_ETag 。 
Spring 3.0还专门为此提供了一个org.springframework.web.filter.ShallowEtagHeaderFilter(实现原理很简单,对JSP输出的内容MD5,这样内容有变化ETag就相应变化了),用于生成响应的ETag,因为这东东确实可以帮助减少请求和响应的交互。

下面是一个ETag:

Java代码  
  1. ETag: "737060cd8c284d8af7ad3082f209582d"

Location

我们在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的,如下的报文头属性,将使客户端redirect到iteye的首页中:

Java代码  
  1. Location: http://www.iteye.com

Set-Cookie

服务端可以设置客户端的Cookie,其原理就是通过这个响应报文头属性实现的:

Java代码  
  1. Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1

其它HTTP响应报文头属性

更多其它的HTTP响应头报文,参见: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

如何写HTTP请求报文头

在服务端可以通过HttpServletResponse的API写响应报文头的属性:

Java代码  
  1. //添加一个响应报文头属性
  2. void    setHeader(String name, String value)

象Cookie,Location这些响应都是有福之人,HttpServletResponse为它们都提供了VIP版的API:

Java代码  
  1. //添加Cookie报文头属性
  2. void addCookie(Cookie cookie)
  3. //不但会设置Location的响应报文头,还会生成303的状态码呢,两者天仙配呢
  4. void    sendRedirect(String location)

8. Http的状态码含义。

一、HTTP码应码
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。

响应码分五种类型,由它们的第一位数字表示:
1.1xx:信息,请求收到,继续处理
2.2xx:成功,行为被成功地接受、理解和采纳
3.3xx:重定向,为了完成请求,必须进一步执行的动作
4.4xx:客户端错误,请求包含语法错误或者请求无法实现
5.5xx:服务器错误,服务器不能实现一种明显无效的请求

下表显示每个响应码及其含义:
100 继续
101 分组交换协
200 OK
201 被创建
202 被采纳
203 非授权信息
204 无内容
205 重置内容
206 部分内容
300 多选项
301 永久地传送
302 找到
303 参见其他
304 未改动
305 使用代理
307 暂时重定向
400 错误请求
401 未授权
402 要求付费
403 禁止
404 未找到
405 不允许的方法
406 不被采纳
407 要求代理授权
408 请求超时
409 冲突
410 过期的
411 要求的长度
412 前提不成立
413 请求实例太大
414 请求URI太大
415 不支持的媒体类型
416 无法满足的请求范围
417 失败的预期
500 内部服务器错误
501 未被使用
502 网关错误
503 不可用的服务
504 网关超时
505 HTTP版本未被支持

二、HTTP头标
头标由主键/值对组成。它们描述客户端或者服务器的属性、被传输的资源以及应该实现连接。

四种不同类型的头标:
1.通用头标:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。
2.请求头标:允许客户端传递关于自身的信息和希望的响应形式。
3.响应头标:服务器和于传递自身信息的响应。
4.实体头标:定义被传送资源的信息。即可用于请求,也可用于响应。

头标格式:<name>:<value><CRLF>

下表描述在HTTP/1.1中用到的头标
Accept 定义客户端可以处理的媒体类型,按优先级排序;
在一个以逗号为分隔的列表中,可以定义多种类型和使用通配符。例如:Accept: image/jpeg,image/png,*/*
Accept-Charset 
定义客户端可以处理的字符集,按优先级排序;
在一个以逗号为分隔的列表中,可以定义多种类型和使用通配符。例如:Accept-Charset: iso-8859-1,*,utf-8

Accept-Encoding 定义客户端可以理解的编码机制。例如:Accept-Encoding:gzip,compress
Accept-Language 定义客户端乐于接受的自然语言列表。例如:Accept-Language:en,de

Accept-Ranges 
一个响应头标,它允许服务器指明:将在给定的偏移和长度处,为资源组成部分的接受请求。
该头标的值被理解为请求范围的度量单位。例如Accept-Ranges: bytes或Accept-Ranges: nonea

Age 允许服务器规定自服务器生成该响应以来所经过的时间长度,以秒为单位。
该头标主要用于缓存响应。例如:Age: 30

Allow 一个响应头标,它定义一个由位于请求URI中的次源所支持的HTTP方法列表。例如:Allow: GET,PUT

aUTHORIZATION 
一个响应头标,用于定义访问一种资源所必需的授权(域和被编码的用户ID与口令)。
例如:Authorization: Basic YXV0aG9yOnBoaWw=

Cache-Control 一个用于定义缓存指令的通用头标。例如:Cache-Control:max-age=30
Connection 一个用于表明是否保存socket连接为开放的通用头标。例如:Connection: close或Connection: keep-alive

Content-Base 
一种定义基本URI的实体头标,为了在实体范围内解析相对URLs。
如果没有定义Content-Base头标解析相对URLs,使用Content-Location URI(存在且绝对)或使用URI请求。
例如:Content-Base: Http://www.myweb.com

Content-Encoding 一种介质类型修饰符,标明一个实体是如何编码的。例如:Content-Encoding:zip
Content-Language 用于指定在输入流中数据的自然语言类型。例如:Content-Language:en
Content-Length 指定包含于请求或响应中数据的字节长度。例如:Content-Length:382

Content-Location
指定包含于请求或响应中的资源定位(URI)。
如果是一绝。对URL它也作为被解析实体的相对URL的出发点。
例如:Content-Location: http://www.myweb.com/news

Content-MD5
实体的一种MD5摘要,用作校验和。
发送方和接受方都计算MD5摘要,接受方将其计算的值与此头标中传递的值进行比较。
例如:Content-MD5: <base64 of 128 MD5 digest>

Content-Range 
随部分实体一同发送;标明被插入字节的低位与高位字节偏移,也标明此实体的总长度。
例如:Content-Range: 1001-2000/5000

Contern-Type 标明发送或者接收的实体的MIME类型。例如:Content-Type:text/html
Date 发送HTTP消息的日期。例如:Date: Mon,10PR18:42:51 GMT

ETag 一种实体头标,它向被发送的资源分派一个唯一的标识符。
对于可以使用多种URL请求的资源,ETag可以用于确定实际被发送的资源是否为同一资源。
例如:ETag: "208f-419e-30f8dc99"

Expires 指定实体的有效期。例如:Expires: Mon,05 Dec 2008 12:00:00 GMT
Form 一种请求头标,给定控制用户代理的人工用户的电子邮件地址。例如:From:webmaster@myweb.com
Host 被请求资源的主机名。对于使用HTTP/1.1的请求而言,此域是强制性的。例如:Host:www.myweb.com

If-Modified-Since 
如果包含了GET请求,导致该请求条件性地依赖于资源上次修改日期。
如果出现了此头标,并且自指定日期以来,此资源已被修改,应该反回一个304响应代码。
例如:If-Modified-Since: Mon,10PR 18:42:51 GMT

If-Match 如果包含于一个请求,指定一个或者多个实体标记。只发送其ETag与列表中标记区配的资源。
例如:If-Match: "208f-419e-308dc99"

If-None-Match 
如果包含一个请求,指定一个或者多个实体标记。资源的ETag不与列表中的任何一个条件匹配,操作才执行。
例如:If-None-Match: "208f-419e-308dc99"

If-Range
指定资源的一个实体标记,客户端已经拥有此资源的一个拷贝。必须与Range头标一同使用。
如果此实体自上次被客户端检索以来,还不曾修改过,那么服务器只发送指定的范围,否则它将发送整个资源。
例如:Range: byte=0-499<CRLF>If-Range:"208f-419e-30f8dc99"

If-Unmodified-Since
只有自指定的日期以来,被请求的实体还不曾被修改过,才会返回此实体。
例如:If-Unmodified-Since:Mon,10PR 18:42:51 GMT

Last-Modified 指定被请求资源上次被修改的日期和时间。例如:Last-Modified:Mon,10PR 18:42:51 GMT
Location 
对于一个已经移动的资源,用于重定向请求者至另一个位置。
与状态编码302(暂时移动)或者301(永久性移动)配合使用。
例如:Location: http://www2.myweb.com/index.jsp

Max-Forwards 
一个用于TRACE方法的请求头标,以指定代理或网关的最大数目,该请求通过网关才得以路由。
在通过请求传递之前,代理或网关应该减少此数目。例如:Max-Forwards: 3

Pragma 一个通用头标,它发送实现相关的信息。例如:Pragma: no-cache
Proxy-Authenticate
类似于WWW-Authenticate,便是有意请求只来自请求链(代理)的下一个服务器的认证。
例如:Proxy-Authenticate: Basic realm-admin

Proxy-Proxy-Authorization
类似于授权,但并非有意传递任何比在即时服务器链中更进一步的内容。
例如:Proxy-Proxy-Authorization: Basic YXV0aG9yOnBoaWw=

Public 列表显示服务器所支持的方法集。例如:Public:OPTIONS,MGET,MHEAD,GET,HEAD
Range 指定一种度量单位和一个部分被请求资源的偏移范围。例如:Range:bytes=206-5513

Refener
一种请求头标域,标明产生请求的初始资源。对于HTML表单,它包含此表单的Web页面的地址。
例如:Refener: http://www.myweb.com/news/search.html

Retry-After 
一种响应头标域,由服务器与状态编码503(无法提供服务)配合发送,以标明再次请求之前应该等待多长时间。
此时间即可以是一种日期,也可以是一种秒单位。例如:Retry-After: 18

Server 一种标明Web服务器软件及其版本号的头标。例如:Server:Apache/2.0.46(Win32)
Transfer-Encoding 一种通用头标,标明对应被接受方反向的消息体实施变换的类型。例如:Transfer-Encoding:chunked

Upgrade 
允许服务器指定一种新的协议或者新的协议版本,与响应编码101(切换协议)配合使用。
例如:Upgrade: HTTP/2.0

User-Agent
定义用于产生请求的软件类型(典型的如Web浏览器)。
例如:User-Agent: Mozilla/4.0(compatible; MSIE 5.5; Windows NT; DigExt)

Vary 一个响应头标,用于表示使用服务器驱动的协商从可用的响应表示中选择响应实体。例如:Vary: *
Via 一个包含所有中间主机和协议的通用头标,用于满足请求。例如:Via: 1.0fred.com, 1.1 wilma.com
Warning 用于提供关于响应状态补充信息的响应头标。例如:Warning: 99www.myweb.com Piano needs tuning

www-Authenticate
一个提示用户代理提供用户名和口令的响应头标,与状态编码401(未授权)配合使用。响应一个授权头标。
例如:www-Authenticate: Basic realm=zxm.mgmt

9. Http request的几种类型。

10. Http1.1和Http1.0的区别

区别:
1,HTTP/1.0协议使用非持久连接,即在非持久连接下,一个tcp连接只传输一个Web对象,;
2,HTTP/1.1默认使用持久连接(然而,HTTP/1.1协议的客户机和服务器可以配置成使用非持久连接)。

在持久连接下,不必为每个Web对象的传送建立一个新的连接,一个连接中可以传输多个对象!

HTTP 1.1与HTTP 1.0的比较

一个WEB站点每天可能要接收到上百万的用户请求,为了提高系统的效率,HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。但是,这也造成了一些性能上的缺陷,例如,一个包含有许多图像的网页文件中并没有包含真正的图像数据内容,而只是指明了这些图像的URL地址,当WEB浏览器访问这个网页文件时,浏览器首先要发出针对该网页文件的请求,当浏览器解析WEB服务器返回的该网页文档中的HTML内容时,发现其中的<img>图像标签后,浏览器将根据<img>标签中的src属性所指定的URL地址再次向服务器发出下载图像数据的请求,如图3.3所示。

图3.3

显然,访问一个包含有许多图像的网页文件的整个过程包含了多次请求和响应,每次请求和响应都需要建立一个单独的连接,每次连接只是传输一个文档和图像,上一次和下一次请求完全分离。即使图像文件都很小,但是客户端和服务器端每次建立和关闭连接却是一个相对比较费时的过程,并且会严重影响客户机和服务器的性能。当一个网页文件中包含Applet,JavaScript文件,CSS文件等内容时,也会出现类似上述的情况。

为了克服HTTP 1.0的这个缺陷,HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。基于HTTP 1.1协议的客户机与服务器的信息交换过程,如图3.4所示。

图3.4

可见,HTTP 1.1在继承了HTTP 1.0优点的基础上,也克服了HTTP 1.0的性能问题。不仅如此,HTTP 1.1还通过增加更多的请求头和响应头来改进和扩充HTTP 1.0的功能。例如,由于HTTP 1.0不支持Host请求头字段,WEB浏览器无法使用主机头名来明确表示要访问服务器上的哪个WEB站点,这样就无法使用WEB服务器在同一个IP地址和端口号上配置多个虚拟WEB站点。在HTTP 1.1中增加Host请求头字段后,WEB浏览器可以使用主机头名来明确表示要访问服务器上的哪个WEB站点,这才实现了在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点。HTTP 1.1的持续连接,也需要增加新的请求头来帮助实现,例如,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。HTTP 1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。

《深入体验Java Web开发内幕——核心基础》

HTTP 协议老的标准是HTTP/1.0,目前最通用的标准是HTTP/1.1。HTTP/1.1是在HTTP/1.0基础上的升级,增加了一些功能,全面兼容 HTTP/1.0。HTTP/1.0不支持文件断点续传,目前的Web服务器绝大多数都采用了HTTP/1.1。
RANGE:bytes是HTTP/1.1新增内容,HTTP/1.0每次传送文件都是从文件头开始,即0字节处开始。RANGE:bytes=XXXX表示要求服务器从文件XXXX字节处开始传送,这就是我们平时所说的断点续传!

原文英文版
RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0
http://www.w3.org/Protocols/rfc1945/rfc1945
http://www.faqs.org/rfcs/rfc1945.html

RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1
http://www.w3.org/Protocols/rfc2616/rfc2616
http://www.w3.org/Protocols/rfc2616/rfc2616.html
http://www.faqs.org/rfcs/rfc2616.html

(Proposed) HTTP-NG Working Group
http://www.w3.org/Protocols/HTTP-NG/
下一代超文本传输协议(HTTP-NG),为了克服当前HTTP协议的缺点,W3C(World Wide Web consortium)开始研究制定下一代HTTP协议?TTP-NG。它分三个层次:应用层、消息层、传输层。现有WEB上应用将转换到HTTP-NG 平台上,最后整个平台都会更新为HTTP-NG。

RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0 中文版
http://man.chinaunix.net/develop/rfc/RFC1945.txt
http://www.cnpaf.net/rfc/rfc1945.txt

RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 中文版

1.0与1.1的区别,英文版
Key Differences between HTTP/1.0 and HTTP/1.1
http://www.research.att.com/%7Ebala/papers/h0vh1.html

中文翻译版没有看到,有看到的告诉我:)

附上:HTTP 1.1状态代码及其含义
状态代码  状态信息  含义  
100  Continue  初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新)  
101  Switching Protocols  服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新)  
200  OK  一切正常,对GET和POST请求的应答文档跟在后面。 
201  Created  服务器已经创建了文档,Location头给出了它的URL。  
202  Accepted  已经接受请求,但处理尚未完成。  
203  Non-Authoritative Information  文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝(HTTP 1.1新)。  
204  No Content  没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。  
205  Reset Content  没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容(HTTP 1.1新)。  
206  Partial Content  客户发送了一个带有Range头的GET请求,服务器完成了它(HTTP 1.1新)。  
300  Multiple Choices  客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。  
301  Moved Permanently  客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。  
302  Found  类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。 
出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。

注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求http://host/~user(缺少了后面的斜杠),有的服务器返回301,有的则返回302。

严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 
 
303  See Other  类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取(HTTP 1.1新)。  
304  Not Modified  客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。  
305  Use Proxy  客户请求的文档应该通过Location头所指明的代理服务器提取(HTTP 1.1新)。  
307  Temporary Redirect  和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。(HTTP 1.1新)  
400  Bad Request  请求出现语法错误。  
401  Unauthorized  客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。  
403  Forbidden  资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。  
404  Not Found  无法找到指定位置的资源。这也是一个常用的应答。  
405  Method Not Allowed  请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用。(HTTP 1.1新)  
406  Not Acceptable  指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容(HTTP 1.1新)。  
407  Proxy Authentication Required  类似于401,表示客户必须先经过代理服务器的授权。(HTTP 1.1新)  
408  Request Timeout  在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新)  
409  Conflict  通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。(HTTP 1.1新)  
410  Gone  所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。(HTTP 1.1新)  
411  Length Required  服务器不能处理请求,除非客户发送一个Content-Length头。(HTTP 1.1新)  
412  Precondition Failed  请求头中指定的一些前提条件失败(HTTP 1.1新)。  
413  Request Entity Too Large  目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头(HTTP 1.1新)。  
414  Request URI Too Long  URI太长(HTTP 1.1新)。  
416  Requested Range Not Satisfiable  服务器不能满足客户在请求中指定的Range头。(HTTP 1.1新)  
500  Internal Server Error  服务器遇到了意料不到的情况,不能完成客户的请求。  
501  Not Implemented  服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求。  
502  Bad Gateway  服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。  
503  Service Unavailable  服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。  
504  Gateway Timeout  由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。(HTTP 1.1新)  
505  HTTP Version Not Supported  服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新)

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

11. Http怎么处理长连接。

第一章

HTTP

长连接与短连接

 

1. 

HTTP

协议与

TCP/IP

协议的关系

HTTP

的长连接和短连接本质上是

TCP

长连接和短连接。

HTTP

属于应用层协议,在传输

层使用

TCP

协议,在网络层使用

IP

协议。

IP

协议主要解决网络路由和寻址问题,

TCP

议主要解决如何在

IP

层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有

包,并且顺序与发出顺序一致。

TCP

有可靠,面向连接的特点。

2. 

如何理解

HTTP

协议是无状态的

HTTP

协议是无状态的,

指的是协议对于事务处理没有记忆能力,

服务器不知道客户端是什

么状态。

也就是说,

打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任

何联系。

HTTP

一个无状态的面向连接的协议,

无状

态不代表

HTTP

不能保持

TCP

连接,

更不能代表

HTTP

使用的是

UDP

协议(无连接)。

3. 

什么是长连接、短连接?

HTTP/1.0

中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次

HTTP

作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个

HTML

或其

他类型的

Web

页中包含有其他的

Web

资源,如

JavaScript

文件、图像文件、

CSS

文件

等;当浏览器每遇到这样一个

Web

资源,就会建立一个

HTTP

会话。

但从

HTTP/1.1

起,默认使用长连接,用以保持连接特性。使用长连接的

HTTP

协议,会

在响应头有加入这行代码:

?

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输

HTTP

据的

TCP

连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已

经建立的连接。

Keep-Alive

不会永久保持连接,它有一个保持时间,可以在不同的服务器

软件(如

Apache

)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP

协议的长连接和短连接,实质上是

TCP

协议的长连接和短连接。

3.1 

TCP

连接

当网络通信时采用

TCP

协议时,

在真正的读写操作之前,

server

client

之间必须建立一

个连接,

当读写操作完成后,

双方不再需要这个连接时它们可以释放这个连接,

连接的建立

是需要三次握手的,而释放则需要

4

次握手,所以说每个连接的建立都是需要资源消耗和

时间消耗的

经典的三次握手示意图:

经典的四次握手关闭图:

3.2 

TCP

短连接

我们模拟一下

TCP

短连接的情况,

client

server

发起连接请求,

server

接到请求,然

后双方建立连接。

client

server

发送消息,

server

回应

client

,然后一次读写就完成

了,

这时候双方任何一个都可以发起

close

操作,

不过一般都是

client

先发起

close

操作。

为什么呢,

一般的

server

不会回复完

client

后立即关闭连接的,

当然不排除有特殊的情况。

从上面的描述看,短连接一般只会在

client/server

间传递一次读写操作

短连接的优点是:

管理起来比较简单,

存在的连接都是有用的连接,

不需要额外的控制手段

3.3 

TCP

长连接

接下来我们再模拟一下长连接的情况,

client

server

发起连接,

server

接受

client

接,

双方建立连接。

Client

server

完成一次读写之后,

它们之间的连接并不会主动关闭,

后续的读写操作会继续使用这个连接。

首先说一下

TCP/IP

详解上讲到的

TCP

保活功能,保活功能主要为服务器应用提供,服务

器应用希望知道客户主机是否崩溃,

从而可以代表客户使用资源。

如果客户已经消失,

使得

服务器上保留一个半开放的连接,

而服务器又在等待来自客户端的数据,

则服务器将应远等

待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作,

则服务器就向客户发一个探测报文段,

户主机必须处于以下

4

个状态之一:

1.

客户主机依然正常运行,并从服务器可达。客户的

TCP

响应正常,而服务器也知道对

方是正常的,服务器在两小时后将保活定时器复位。

2.

客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的

TCP

没有响应。服务端将不能收到对探测的响应,并在

75

秒后超时。服务器总共发送

10

个这样的探测,每个间隔

75

秒。如果服务器没有收到一个响应,它就认为客户主机

已经关闭并终止连接。

3.

客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是

一个复位,使得服务器终止这个连接。

4.

客户机正常运行,但是服务器不可达,这种情况与

2

类似,

TCP

能发现的就是没有收

到探查的响应。

4. 

长连接和短连接的优点和缺点

由上可以看出,长连接可以省去较多的

TCP

建立和关闭的操作,减少浪费,节约时间。对

于频繁请求资源的客户来说,

较适用长连接。

不过这里存在一个问题,

存活功能的探测周期

太长,还有就是它只是探测

TCP

连接的存活,属于比较斯文的做法,遇到恶意的连接时,

保活功能就不够使了。

在长连接的应用场景下,

client

端一般不会主动关闭它们之间的连接,

Client

server

之间的连接如果一直不关闭的话,会存在一个问题,

随着客户端连接越来

越多,

server

早晚有扛不住的时候,这时候

server

端需要采取一些策略,如关闭一些长

时间没有读写事件发生的连接,这样可以避免一些恶意连接导致

server

端服务受损;如果

条件再允许就可以以客户端机器为颗粒度,

限制每个客户端的最大长连接数,

这样可以完全

避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,

存在的连接都是有用的连接,

不需要额外的控制手段。

但如果客户请求频繁,将在

TCP

的建立和关闭操作上浪费时间和带宽。

长连接和短连接的产生在于

client

server

采取的关闭策略,

具体的应用场景采用具体的

策略,没有十全十美的选择,只有合适的选择。

12. Cookie与Session的作用于原理。

作用:
服务器可以利用Cookies或Session包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状态。它们最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续。另一个重要应用场合是“购物车”之类处理。用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入Cookies或Session,以便在最后付款时提取信息。总而言之,cookies和session就是能够记录顾客状态的技术,尽管二者属于不同的技术,但只要cookies能做到的,session也能做到

区别和联系、工作原理等:
打个比方:在河南时,我常到一家熟食店买馋嘴鸭,该店老板为了促进销售,特发布“每购满10只即可免费赠送一只”的优惠措施。除了家里有什么红白喜事要飨客之外,应该不会有人一次性购买10只烤鸭吧?所以老板得想个法子来记录顾客的消费数量,这里总共有三种方案:
Ⅰ、老板记住每一个顾客的消费数量,等到顾客消费满10只的时候自动奉送一只。这好比HTTP协议本身是有状态的,可以记住顾客的活动行为。但遗憾的是,出于种种考虑http协议本身是不能有状态的,老板自个也没有这么超常的记忆力,故这种方案行不通!
Ⅱ、老板发给顾客一张积分卡,上面记录着消费的数量,一般还有个有效期限。每次买烤鸭时,如果顾客出示这张卡片,老板就知道这位顾客曾经光顾过小店。这种做法就是在客户端保持状态,好比是cookie技术。打开(windows系统)C:\Documents and Settings\用户名\Cookies,你会发现一些*.txt格式的小文件,这就是你浏览某些网站,它们发给你的“积分卡”(cookies)。
Ⅲ、老板发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次买烤鸭时,如果顾客出示该卡片,则老板搬出店里的划名册,找到你的卡号并加1个积分。这种做法就是在服务器端保持状态。
好比是session技术。
cookie和session最大的区别在于: cookie是把积分卡发给顾客,上面记录了顾客所有的消费信息。Session则是把只有卡号(session id)的积分卡发给顾客,自家记录了顾客所有的消费信息。Cookie是保存在客户端的;session是保存在服务器端,而session id则是保存在客户端,通常也是一个cookie小文件,由于这个小文件除了session id(好比卡号)外什么也没有,因此比cookie安全多了。

具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。

cookie机制。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式

session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

13. 电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。

https://github.com/skyline75489/what-happens-when-zh_CN

打开浏览器输入网址,客户端反复寻求名称服务器来获得解析结果,之后通过地址解析将IP转换成MAC: 1)、查缓存 2)、在缓存里查不到就发ARP请求 3)、目的主机受到ARP请求后,就记录请求主机的MAC地址,然后发送ARP应答 4)、主机收到后就记录目的主机的MAC地址,然后发送数据 HTTP封装在TCP中,TCP封装在IP中,IP封装在DLC中,TCP使用80端口应用HTTP协议,TCP和IP的首部长度为20-60字节。

14. Ping的整个过程。ICMP报文是什么。

Ping过程详解

Ping命令的主要作用的是检查网络的连通情况和检测网络的速度。相信大家都用过Ping命令,下面主要介绍一下Ping命令是怎样一个执行过程。

主要的Ping有两种情况,一种是同一网段,一种是跨网段的。

首先看一个拓扑图:

首先,如果主机A要Ping主机B,那么主机A就要封装二层报文,他会先检查自己的MAC地址,如果没有B的MAC地址,就会向外发送一个ARP广播包,如图:

其中ARP报文格式如下:

其中OP表示:1:表示ARP请求;2:表示ARP应答;3:表示RARP请求;4:表示RARP应答。

首先交换机会收到这个报文后,交换机有学习MAC地址的功能,所以他会检索自己有没有保存主机B的MAC地址,如果有的,就直接返回给A主机,如果没有,就会向所有端口发送ARP广播,其他主机收到后,发现不是在找自己,就纷纷丢弃了改报文,不去理会,直到主机B收到了报文后,就立即响应,我的MAC地址是多少,同时学到主机A的MAC地址,并按同样的ARP报文格式返回给主机A。如图:

ARP报文的格式为:

这时候主机A 学到了主机B的MAC地址,就把这个MAC封装到ICMP协议的二层报文中向主机B发送,报文格式如下:

当主机B收到了这个报文后,发现是主机A的ICMP回显请求,就按同样的格式,返回一个值给主机A,这样就完成了同一网段内的Ping过程。

如果主机A要Ping主机C,那么主机A发现主机C的IP和自己的IP不是同一个网段,他就去找网管转发,但是他也不知道网管的MAC情况下呢?这是就会像前面那个步骤一样,先发送一个ARP广播,学到网关的MAC地址,再发封装包,报文的格式如下:

当路由器收到主机A发过来的ICMP报文,发现自己的母的地址是其本身MAC地址,根据母的地IP地址2.1.1.1,查找路由表,发现2.1.1.1/24的路由表项,得到一个出口指针,去掉原来的MAC头部,加上自己的MAC地址向主机C转发,报文格式如下   

最后主机C已学到路由器2端口MAC,路由器2端口转发给路由器1端口,路由器端口学到主机A的MAC地址的情况下,他们就不需要再做ARP解析,就将ICMP的回显请求恢复过来,报文格式如下:

ICMP报文分析

一.概述:

1.   ICMP允许主机或路由报告差错情况和提供有关异常情况。ICMP是因特网的标准协议,但ICMP不是高层协议,而是IP层的协议。通常ICMP报文被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。
2.   ICMP报文作为IP层数据报的数据,加上数据报的首部,组成数据报发送出去。
3.   ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。
二.ICMP报文的格式

1.   类型:占8位
2.   代码:占8位
3.   检验和:占16位
说明:ICMP所有报文的前4个字节都是一样的,但是剩下的其他字节则互不相同。
4.   其它字段都ICMP报文类型不同而不同。
1>  ICMP报文的前4个字节是统一的格式,共有三个字段:即类型,代码和检验和。
2>  8位类型和8位代码字段一起决定了ICMP报文的类型。
类型8,代码0:表示回显请求(ping请求)。
类型0,代码0:表示回显应答(ping应答)
类型11,代码0:超时
3>16位的检验和字段:包括数据在内的整个ICMP数据包的检验和;其计算方法和IP头部检验和的计算方法一样的。
ICMP报文具体分为查询报文和差错报文(对ICMP差错报文有时需要做特殊处理,因此要对其进行区分。如:对ICMP差错报文进行响应时,永远不会生成另一份ICMP差错报文,否则会出现死循环)
三、ICMP差错报文(56字节)
1.   ICMP差错报告报文共有5种
1>  终点不可达:终点不可达分为:网络不可达,主机不可达,协议不可达,端口不可达,需要分片但DF比特已置为1,以及源路由失败等六种情况,其代码字段分别置为0至5。当出现以上六种情况时就向源站发送终点不可达报文。
说明:
端口不可达:UDP的规则之一是:如果收到UDP数据报而且目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文。
2>  源站抑制:当 路由器或主机由于拥塞而丢弃数据报时,就向源站发送源站抑制报文,使源站知道应当将数据报的发送速率放慢。
3>  时间超过:当路由器收到生存时间为零的数据报时,除丢弃该数据报外,还要向源站发送时间超过报文。当目的站在预先规定的时间内不能收到一个数据报的全部数据报片时,就将已收到的数据报片都丢弃,并向源站发送时间超过报文。
4>  参数问题:当路由器或目的主机收到的数据报的首部中的字段的值不正确时,就丢弃该数据报,并向源站发送参数问题报文。
5>  改变路由(重定向)路由器将改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器。
说明:
以下几种情况都不会导致产生ICMP差错报文
1>ICMP差错报文(但是,ICMP查询报文可能会产生ICMP差错报文)
2>目的地址是广播地址或多播地址的IP数据报
3>作为链路层广播的数据报
4>不是IP分片的第一片
5>源地址不是单个主机的数据报。即源地址不能为零地址、环回地址、广播地址或多播地址。
这些规则是为了防止过去允许ICMP差错报文对广播分组响应所带来的广播风暴。
2.所有的ICMP差错报告报文中的数据字段都具有同样的格式。将收到的需要进行差错报告IP数据报的首部和数据字段的前8个字节提取出来,作为ICMP报文的数据字段。再加上响应的ICMP差错报告报文的前8个字节,就构成了ICMP差错报告报文。提取收到的数据报的数据字段的前8个字节是为了得到运输层的端口号(对于TCP和UDP)以及运输层报文的发送序号(对于TCP)。

注:一下情况不发送ICMP差错报告报文
三.ICMP询问报文(40字节)

1.ICMP询问报文有四种回送请求和回答,时间戳请求和回答,掩码地址请求和回答,以及路由器询问和通过。
1>ICMP回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的机器必须给源主机发送ICMP回送应答报文。这种询问报文用来测试目的站是否可达以及了解其有关状态。
2>ICMP时间戳请求允许 系统向另一个系统查询当前的时间。该ICMP报文的好处是它提供了毫秒级的分辨率,而利用其他方法从别的主机获取的时间只能提供秒级的分辨率。请求端填写发起时间,然后发送报文。应答系统收到请求报文时填写接收时间戳,在发送应答时填写发送时间戳。大多数的实现是把后面两个字段都设成相同的值。
3>主机使用ICMP地址掩码请求报文可向子网掩码服务器得到某个接口的地址掩码。系统广播它的ICMP请求报文。ICMP报文中的标识符和序列号字段由发送端任意选择设定,这些值在应答中将被返回,这样,发送端就可以把应答与请求进行匹配。
4>主机使用ICMP路由器询问和通过报文可了解连接在本网络上的路由器是否正常工作。主机将路由器询问报文进行广播(或多播)。收到询问报文的一个或几个路由器就使用路由器通过报文广播其路由选择信息
四.Ping程序
1.概述
1>Ping程序是为了测试另一台主机是否可达。该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。
2>Ping程序还能测出到这台主机的往返时间,以表明该主机离我们有多远。
2.我们将发送回显请求的ping程序为客户,而称被ping的主机为服务器。
3.ICMP回显请求和回显应答报文格式:

1>Unix系统在实现ping程序时把ICMP报文中的标识符字段置成发送进程的ID号。这样即使在同一台主机上同时运行了多个ping程序实例,ping程序也可以识别出返回的信息。
2>序列号从0开始,每发送一次新的回显请求就加1。ping程序打印出返回的每个分组的序列号,允许我们查看是否有分组丢失,失序或重复。.
3>ping程序通过在ICMP报文中存放发送请求的时间值来计算往返时间。当应答返回时,用当前时间减去存放在ICMP报文中的时间值,即是往返时间。
4>当返回ICMP回显应答时,要打印出序列号和TTL,并计算往返时间。TTL位于IP首部的生存时间字段。ping程序通过在ICMP报文数据段中存放发送请求的时间值来计算往返时间。当应答返回时,用当前时间减去存放在ICMP报文中的时间值,即是往返时间。

ICMP协议是一种面向连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,它对于网络安全具有极其重要的意义。
它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。

ICMP原理
ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型,并确定如何才能更好地重发失败的数据报。但是ICMP唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成。
我们在网络中经常会使用到ICMP协议,比如我们经常使用的用于检查网络通不通的Ping命令(Linux和Windows中均有),这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。

15. C/S模式下使用socket通信,几个关键函数。

Socket

接口用法详解

Java

中,

基于

TCP

协议实现网络通信的类有两个,

在客户端的

Socket

类和在服务器端的

ServerSocket

类,

ServerSocket

类的功能是建立一个

Server

,并通过

accept()

方法随时监听客

户端的连接请求。

扩展:

ServerSocket

中常用的构造函数及方法

构造函数:

ServerSocket(int port)

这是一个构造方法,用于在当前的服务器默认的

IP

地址上监听一个指定的端口,即在指定的

IP

和端口创建一个

ServerSocket

对象

方法:

Socket accept()

产生阻塞,监听指定的端口,直至有客户端发来连接请求

void close()

关闭当前

ServerSocket

InetAddress getInetAddress()

返回

ServerSocket

监听的,本机的

IP

地址

int getLocalPort()

返回

ServerSocket

监听的,本机的

IP

地址上指定的端口号

int

getSoTimeout();void

setSoTimeout(int

timeout)

设置连接过程中没有得到相应的等

待期限时间(

TimeOut

String

toString()

以字符串的方式返回

ServerSocket

监听的,

本机的

IP

地址及其端口

Socket

类中常用的构造函数和方法

构造函数:

Socket(InetAddress

address,int

port)

用于创建一个链接,向指定的

IP

地址

上指定的端口的服务器端程序发送连接请求

Socket(String host,int port)

同上,但该方法允许通过主机名字符串向服务器发送连

接请求

方法:

void close

()关闭当前的

Socket

连接

InetAddress getInetAddress()

返回

Socket

建立了连接的服务器的

IP

地址

InputStream getInputStream()

返回当前

Socket

的输入流

OutputStream getOutStream()

返回当前

Socket

的输出流

InetAddress getLocalAddress()

返回和

Socket

进行连接的本地的

IP

地址

int getLocalPort()

返回和

Socket

进行连接的本地的端口号

int getPort()

返回和

Socket

建立了连接的服务器的端口号

int

getSoTimeOut();void

setSoTimeOut(int

timeout)

设置连接过程中没有得到相应的等

待期限时间

id="ifrId_1434618420266_0" width="0" height="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="width: 960px; height: 90px;">

String toString ()

以字符串的方式返回

Socket

的属性信息

Socket

类的构造方法包括以下几种:

public Socket(String host,int port)

public Socket(InetAddress address,int port)

public Socket(String host,int port,InetAddress localAddr,int localPort)

public Socket(InetAddress host,int port, InetAddress,localAddr,int localPort)

JDK1.1

以前,

Socket

类可同时用于

TCP/UDP

通信:

public Socket(String host,int port,Boolean stream)

public Socket(InetAddress host,int port, Boolean stream)

Socket

类的输入

/

输出流管理包括以下方法:

public InputStream getInputStream()

public void shutdowmInput()

public OutputStream get OutputStream ()

public void shutdowmOutput()

以上这些方法都将抛出

IOException

异常,程序中需要捕获并处理。

关闭

Socket

的方法为:

public void close() throws IOException

设置

/

获取

Socket

数据的方法为:

public InetAddress getInetAddress()

public int getPort()

public void setSoTimeout(int timeout)

这些方法都将抛出

SocketException

异常,程序中需要捕获并处理。

ServerSocket

类的构造方法包括以下几种:

public ServerSocket (int Port)

public ServerSocket (int Port,int backlog):

支持指定数目的连接

public ServerSocket (int Port,int backlog,InetAddress bindAddr)

这些方法都将抛出

IOException

异常,程序中需要捕获并处理。

public Socket

accept():

等待客户端的连接

public void close():

关闭

Socket

设置

/

获取

Socket

数据的方法包括:

public InetAddress

get InetAddress ()

public int getLocalPort()

public void setSoTimeout(int timeout)

这些方法都将抛出

SocketException

异常,程序中需要捕获并处理。

Socket

的基本概念

1

.建立连接

当需要建立网络连接时,

必须有一台机器运行一个程序,

随时等候连接,

而另一端的程序这

对其发出连接请求。

这一点同电话系统类似——必须有一方拨打电话,

而另一方必须等候电

话连通。建立连接的过程为:

1

)现在服务器端生成一个

ServerSocket

实例对象,随时监听客户端的连接请求。

2

当客户端需要连接时,

相应地要生成一个

Socket

实例对象,

并发出连接请求,

其中

host

id="ifrId_1443408483217_0" width="0" height="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="width: 960px; height: 90px;">

参数指明该主机名,

port#

参数指明该主机端口号。

3

服务器端通过

accept()

方法接收到客户端的请求后,

开辟一个接口与之进行连接,

并生

成所需的

I/O

数据流。

4

客户端和服务器端的通信都是通过一对

InputStream

OutputStream

进行的,

通信结束

后,两端分别关闭对应的

Socket

接口。

2.

连接地址

打电话时,

呼叫方必须事先知道所需拨打的号码,

而程序建立网络连接时,

也同样需要知道

地址或主机名称。另外,网络连接还需要一个端口号(可以将其当作电话的分机号)

,连接

到正确的主机之后,

需要对该连接确认特定口令。

某些情况下,

还需要使用一个扩展号码与

网络计费系统相连,于是相应地要有一个特定端口号用于连接计费程序。

3.

端口号

TCP/IP

系统中,端口号由

16

位二进制整数组成,即在

0-65535

之间。实际应用中,前

1024

个端口号已经预先定义为一些特定服务,因此一般不能使用,除非想同这些服务器进

行连接(如

Telnet

SMTP

mail

ftp

等)

。在两个程序连接之前,彼此之间必须达成一致,

即由客户端负责初始化连接,

而服务器随时等候请求。

只有客户端和服务器端指定端口号一

致时连接才会建立。如果系统中两个程序所用端口号不一致,这连接无法建立。

4.

网络连接模式

Java

中,

TCP/IP

接口的连接是由

java.net

包中的类实现的。如图表示的是

Socket

连接过

程中客户端和服务器端的工作原理。

每个

server

端都拥有一个端口号,一台机器上如果运行多个服务,这可能对应多个端口号。

通信结束后,两端分别关闭对应的

Socket

接口,而不影响其他的端口。

Socket

通信的基本步骤

使用

Socket

方式进行网络通信的程序基本结构都是类似的,无论一个

Socket

通信程序的功

能多么齐全、

程序多么复杂,

其基本结构都是一样的。

客户端与服务器端进行通信的过程都

包括以下四个基本步骤:

1

)在服务器端指定一个用来等待连接的端口号,在客户端规定一个主机和端口号,从而

16. IP地址分类。

17. 路由器与交换机区别。

网络其实大体分为两块,一个TCP协议,一个HTTP协议,只要把这两块以及相关协议搞清楚,一般问题不大。

推荐书籍:《TCP/IP协议族》

BAT、网易、蘑菇街面试题整理-6相关推荐

  1. BAT、网易、蘑菇街面试题整理-3

    25. ThreadLocal的设计理念与作用 Why ThreadLocal? 无论如何,要编写一个多线程安全(Thread-safe)的程序是困难的,为了让线程共享资源,必须小心地对共享资源进行同 ...

  2. BAT、网易、蘑菇街面试题整理-8

    Android 1.Activity与Fragment的生命周期. http://blog.csdn.net/zjclugger/article/details/10442335 一.Activity ...

  3. BAT、网易、蘑菇街面试题整理

    1. 八种基本数据类型的大小,以及他们的封装类. byte-Byte      8位 char-Character  16位 short-Short      16位 int-Integer      ...

  4. iOS开发——BAT网易笔试面试题参考答案

    阿里B2B - 一面 1,load方法执行顺序,分类和主类的load方法顺序,两个分类的load方法顺序,跟main函数的顺序 2,sqllite的跟orcale这些大型的数据库的机制有什么不同的? ...

  5. 最全BAT大型互联网公司面试题整理,没有之一

    最近有很多网友都在求大厂面试题.正好我之前电脑里面有这方面的整理,于是就发上来分享给大家. 这些题目是网友去百度.小米.乐视.美团.58.猎豹.360.新浪.搜狐等一线互联网公司面试被问到的题目.熟悉 ...

  6. 史上最全 BAT 大厂面试题整理

    转载自 史上最全 BAT 大厂面试题整理!(速度收藏) 主要分为以下几部分: (1)java面试题 (2)Android面试题 (3)高端技术面试题 (4)非技术性问题&HR问题汇总 1 ja ...

  7. 【直通BAT】剑指Offer 经典试题整理(5)

    45 把数组排成最小的数 题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个. 例如输入数组 [3, 32, 321],则打印出这3个数字能排成的最小 ...

  8. 网易历届笔试面试题整理大全

    整理了一下网易往届笔试面试题,希望对大家有帮助: 超级有用的面试题:Java常见面试题    常见算法面试题   数据库常见面试题  操作系统常见面试题   C/C++常见面试题  大数据常见面试   ...

  9. 2020最全的BAT大厂面试题整理改版

    最全的BAT大厂面试题整理 版权声明:本文为博主原创文章,未经博主允许不得转载.https://www.jianshu.com/p/c70989bd5f29 转载请标明出处: https://www. ...

最新文章

  1. 虚拟dom_通过编写简易虚拟DOM,来学习虚拟DOM 的原理
  2. 1.3 Integer类详解
  3. CAN 多于8字节的拆包组包协议
  4. HBTS(HBOI) 2019 真实退役记
  5. mqtt异步publish方法
  6. Teams Bot 如何使用新的 System.Text.Json 库
  7. Memcache监控小工具stats命令
  8. FlinkCdc从Mysql指定的binlog日志offsetPos位置开始读取数据
  9. Flipping elements with WPF
  10. 苹果Mac触控栏使用技巧
  11. pr用什么显卡比较好_Adobe Premiere视频渲染用的显卡该怎么选?
  12. Word设置封面无页码,摘要罗马数字页码,正文数字页码
  13. 禅道服务器修改ip,访问禅道服务器的ip地址
  14. SVN多项目共享导出及故障处理
  15. 数字音频:音频采样率和位深度
  16. Word不会排版!看这里,3分钟教你学会30个排版技巧
  17. ng-model、ng-bind、ng-value使用区别
  18. python中while循环并列_Python中while循环的一个问题
  19. 企业数字化转型之传统IT架构改造
  20. 5.5 listen() --- 如果有“人”,请叫我?

热门文章

  1. 线性和非线性数据结构分类
  2. 报告解读:双肩包品牌消费趋势洞察(附完整版报告)
  3. 圆的内接三角形这样画最方便
  4. android+sd卡数据恢复,Android备份和恢复SD卡的数据库
  5. 计算机音乐拔剑神曲,泽野弘之的音乐世界,那些拔剑神曲、核爆神曲的名字是什么来的?...
  6. 移动开发作业六 蓝牙通信
  7. 计算机软件著作权申请需要多久
  8. 这所与阿里巴巴有关的大学,计算机专业课也变了!
  9. 几个步骤解决linux做ssh免密之后ssh登陆任然需要密码问题
  10. 使用 MethodInfo 调用带ref参数的方法