网络通信模式
大部分的网络应用系统可以分为连个部分:客户和服务器,而网络服务程序架构有两种一种是CS模式,一种是BS模式。
OSI七层网络模型(open system interconnection,开放系统互联)

1.物理层
2.数据链路层
3.网络层
4.传输层
5.会话层
6.表示层
7.应用层
TCP/IP协议


TCP/IP——网络接口层

主要作用二:控制帧传输。控制帧的传输的主要体现在反馈重发,计时器。帧序号方面。接收方通过对帧的差错编码(奇偶检验码或CRC)的检查,来判断帧在传输过程中是否出错,并向发送方进行反馈,如果传输方发送差错,则需要重发纠正。作为发送方,如果在发送帧后,会同时启动定时器,如果帧发送后在一段时间内没有收到反馈,为了避免传输停滞不前,则在定时器Timeout后认为帧传输出错,自动重发,为了避免多次收到同一帧并将其递交给网络层的情况发生,则需要对每个帧进行编号,接收从此以来判断该帧是否重复接受了。
TCP/IP——网络层
IP协议是TCP/IP协议族中最为核心的协议。所有的TCP,UDP,ICMP,IGMP协议数据都以IP数据报格式传输。IP协议提供的是不可靠的,无连接的数据报传输服务,不可靠是指IP协议不会保证数据报能否到达目的地,仅提供传输服务,传输出错,则会丢弃出错的数据报。无连接是指IP协议对数据报的处理是独立的,这一意味着接收方不一定会按照发送顺序接收数据报。IP数据报格式如下
IP地址分类:
子网划分:
TCP/IP——传输层

TCP协议
TCP(Transmission Control Protocol)传输控制协议,相对于UDP,TCP是面向连接的,提供可靠的数据传输服务。同时也是较UDP开销较大的,传输速度较慢的。
TCP提供可靠的,面向连接的数据传输服务。使用TCP通信之前,需要进行“三次握手”建立连接,通信结束后还要使用“四次握手”断开连接。
TCP是点对点的连接。一条TCP连接只能连接两个端点。 TCP提供可靠传输,无差错,不丢失,不重复,按顺序。 TCP提供全双工通信,允许通信双方任何时候都发送数据,发送方设有发送缓存,接收方设有接收缓存。 TCP面向字节流。TCP并不知道所传输的数据的含义,仅把数据看作一连串的字节序列,它也不保证接收方收到的数据块和发送方发出的数据块具有大小对应关系。
TCP报文结构
TCP是面向字节流的,通过TCP传送的字节流中的每个字节都按顺序编号,而报头中的Sequence Number 字段则指的是本报文段数据的第一个字节的序号,Avknowledgment Number是期望收到对方下个报文段的第一个数据字节的序号。
Offset : 占4位,指TCP报文段的报头长度,包括固定的20字节和TCP Options字段。 Reserved : 占6位,保留为今后使用,目前为0。 TCP flags的C、E、U、A、P、R、S、F字段用来说明改报文的性质。意义如下:
C(CWR)和E(ECE) 用来支持ECN(显示阻塞通告) U(URGENT):当 URG=1时,它告诉系统此报文中有紧急数据,应优先传送(比如紧急关闭),这要与紧急指针字段配合使用。 A(ACK):仅当 ACK=1时确认号字段才有效。建立 TCP 连接后,所有报文段都必须把 ACK 字段置为 1。 P(PUSH):若TCP连接的一端希望另一端立即响应,PSH字段便可以“催促”对方,不再等到缓存区填满才发送。 R(RESET):若 TCP 连接出现严重差错,RST 置为 1,断开 TCP 连接,再重新建立连接。 S(SYN):用于建立和释放连接,当SYN=1时,表示建立连接。 F(FIN):用于释放连接,当 FIN=1,表明发送方已经发送完毕,要求释放TCP 连接。 Window:占2个字节。窗口值是指发送者自己的接收窗口大小,因为接收缓存的空间有限。 CheckSum:占2个字节。和UDP报文一样,有一个检验和,用于检查报文是否在传输过程中出差错。 Urgent Pointer:占2字节。当URG=1时才有效,指出本报文段紧急数据的字节数。
TCP建立连接的三次握手
1.Client首先向Server发送连接请求报文段,同步自己的seq(x),Client进去SYN_SENT状态。2.Server收到Client的连接请求报文段,发回给Client自己的seq(y)以及ack(x+1),Server进去SYN_REVD状态。 3.Client收到Server的返回确认,再次向服务器发送确认报文段ack(y+1),这个报文段已经可以携带数据了。Client进入ESTABLISH状态。 4。Server再次收到Client的确认消息后,进去ESTABLISH状态。
TCP连接至此建立起来了。为什么要做三次握手呢?握手的过程实际上是在通知对方自己的初始化序号(Initila Sequence Number)简称ISN,也就是图上的x和y。x和y会被当做之后传输的一个依据,以保证TCP报文在传输过程中不会混乱。
对于TCP Header的结构来看,Sequence Number和Acknowledgment都是占32位,所以seq和ack的取值范围都是0~2^32-1。seq和ack每增加到2^32-1,都会置为0。值得一提的是,seq的初始值(ISN)并不是每次都从0开始的。我们设想一下,如果是0开始,那么当TCP三次握手建立连接完成后,Client发送了30个报文,然后Client断线了,于是Client重连,再次用0作为初始化的seq,这样就会出现两个报文具有相同的seq,就出现了混乱,事实上TCP的做法是每隔4微秒就对ISN做一次加1的操作,当ISN到达2^32-1后再次从0开始的时候,已经过去了几个小时,之前seq=0的报文已经不存在于这次的连接中了,这样就避免了上面的问题。
TCP断开连接的四次握手
1.Client向Server发送断开连接的请求报文段,seq=m(m为Client最后一次向Server发送报文段的最后一个字节序号加1),Client进入FIN-WAIT状态。 2.Server收到断开报文段后向Client发送确认报文段,seq=(n为Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入CLOSE-WAIT状态。此时这个TCP连接处于半开半闭状态,Server发送数据的话,Client仍然可以接收到。 3.Server向Client发送断开确认报文段,seq=u(u为半开半闭状态下Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入LAST-ACK状态。 4.Client收到Server的断开确认后报文段后,向Server发送确认断开报文seq=m+1,ack=u+1,Client进入TIME-WAIT状态。 5.Server收到Client的确认断开报文,进入CLOSED状态,断开了TCP连接。 6.Client在TIME-WAIT状态等待一段时间(时间为2*MSL)(Maximum Segment Life),确认Client向Server发送的最后一次断开确认到达(如果没有到达,Server会重发步骤(3)中的断开确认报文段给Client,告诉Client你的最后一次确认断开没有收到)。如果Client在TIME-WAIT过程中没有再次收到Server的报文段,就进入CLOSED状态。TCP连接至此断开。
TCP可靠连接的体现:
1.TCP报文段的长度可变,根据收发双方的缓存状态,网络状态而调整。 2.当TCP收到发自TCP连接另一端的数据,他将发送一个确认。 3.当TCP发出一个段后,他启动一个定时器,等待目的端确认收到这个报文段,如果不嗯呢该几首收到一个确认,将重发这个报文段。 4.TCP将保持这它首部和数据的校验和,如果通过校验和发现报文段有错,这个报文段将被丢失,等待超时重传。 需要注意的是,TCP报文传输采用接收后返回确认的方式来保证报文传输的可靠性,并不是意味着发送方在发送一个报文段后就进入等待确认状态,让后面的报文段等着。也不是接收方在接收到一个报文后,对每一个报文都进行回复确认。 真实的情况是,对于发送方,在发送一个报文段后,复制一份该报文段的副本,然后继续进行下一个报文段的发送,如果没 有得到发送方的回复确认,就对该报文段进行超时重发。对于接收方来说,则采用“积累确认”的方式进行回复。接收者收到多个连续的报文段后,只回复确认最后一个报文段,表示在这之前的数据都已收到。以此达到提升传输效率的目的。
TCP流量控制:
由于收发双方缓存的限制,发送窗口不能大于接收方接收窗口。在报文段首部有一个字段就叫做窗口(rwnd),这便是用于告诉对方自己的接收窗口,可见窗口的大小是可以变化的,这个叫做滑动窗口协议。
TCP/IP——应用层
关于应用层协议,不同的应用或者具体来说同一种应用不同的需求,都会使用不同的应用层协议。下面是常见的应用协议使用的端口:
端口号 | 名称 | 说明 |
20 | ftp-data | FTP(数据端口) |
21 | ftp | 文件传输协议(FTP)控制端口 |
22 | ssh | 安全Shell(SSH)远程登录服务 |
23 | telent | Telnet远程登录服务 |
25 | smtp | 简单邮件传输协议(SMTP) |
53 | dns | 域名服务(Domain Name Server) |
69 | tftp | 简单文件传输协议 |
80 | http | 用于万维网(WWW)服务的超文本传输协议 |
123 | ntp | 网络时间协议(NTP) |
161/162 | snmp | 简单网络管理协议(SNMP) |
443 | https | 安全超文本传输协议(HTTPS) |
1433 | mysql | mysql数据库服务程序默认端口 |
8080 | tomcat | java服务器程序默认端口 |
因为端口号是16位的。这也意味着端口号的范围是0~65536。其中1~1024是被RFC3232规定好了的,被称作"众所周知的端口",监听该范围内的端口程序必须以ROOT权限运行;从1025~65535端口被称为动态端口(Dynamic Ports),可以来建立与其它主机的会话,也可由用户自定义用途。所以我们在写服务器程序时,一般使用该范围内的端口,当然应该避免一些知名的端口或当前正在使用的端口。我们可以通过sudo netstat -tlnp查看被监听的端口。
一台服务器主机可以提供多种服务,譬如一台Linux主机可以提供SSH服务,这样我们就可以使用SSH西医的客户端软件(如SecureCRT,Putty)来远程登录控制;当然也可以在Linux主机上同时提供web服务,这样我们就可以通过浏览器访问架设在主机上的网站。 对每一个服务,都会有一个相应的程序在后台默默地运行着提供相应的服务,其中openssh或dropbear就是实现ssh协议额的服务程序,apache,nginx,httpd,boa等是提供web访问的web服务器。既然同一台服务器可以提供这么多服务,那么当某个客户端程序访问服务器的时候,系统 怎么知道该客户端是访问哪个服务器程序,这也决定了从网卡上收到的数据包究竟该给哪个服务器程序。其实,每一个服务器程 序都会监听一个特定的端口,并且这个端口不可被其他程序重用,同时每一个客户端在访问某个服务器时,除了指定服务器的地 址(包括域名和IP地址)还需要说明要访问哪个端口,那么从该客户端过来的数据系统会给监听相应端口的服务器程序。
在很多客户端软件上,如果没有指端口的话譬如我们使用浏览器上网,通常只是输入域名(如www.baidu.com),而并没有端口,事实上这是因为浏览器会默认访问80端口。而如果想访问某个特定的端口,我们可以在域名后添加相应的端口来访问,如:https://baidu.com:443,用该地址可以访问百度服务器的443端口。在这里得实例中,www指定是http协议,https指定的是https协议,baidu.com指定的是百度的域名,系统会查询DNS将该域名转换成IP地址,而:443则指定访问的端口,SSL默认使443端口。
举例子:
