一,软件开发的架构 1: C/S 架构
Client 与 Server 客户端与服务器端,这里的客户端一般泛指客户端应用 EXE,程序需要先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖较大.
2: B/S 架构
Browser 与 Server 浏览器端与服务器端.
Browser 浏览器,其实也是一种 Client 客户端,只是这个客户端不需要去安装什么应用程序,只需在浏览器上通过 HTTP 请求服务器端相关的资源.
二,网络基础
IP 地址:指互联网协议地址.
IP 地址是 IP 协会提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异.
IP 地址是一个 32 位的二进制数,通常被分割为 4 个'8 位二进制数'.
IP 地址通常用 "点分十进制" 表示(a,b,c,d)的形式,其中,a,b,c,d 都是 0~255 之间的十进制整数.
端口可以认为是设备与外界通讯交流的出口.
因此 IP 地址可以精确到具体的一台电脑,而端口精确到具体的程序.
通过子网掩码,我们就能判断,任意两个 IP 地址是否处在同一个子网络.方法是将两个 IP 地址与子网掩码分别进行 AND 运算(两个位数都是 1,则结果 1,反之 0),然后比较结果是否相同,如果是的话,就表示它们在同一个子网络中,否则就不是.
总结一下,IP 协议的作用主要有两个:一个是为每一台计算机分配 IP 地址,另一个是确定哪些地址在同一个子网络.
TCP 协议
TCP--- 传输控制协议,提供的是面向连接,可靠的字节流服务.当客户与服务器彼此交换数据前,必须先在双方之间建立一个 TCP 连接,之后才能传输数据.TCP 提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传输到另一端.
可靠的,面向连接的协议(eg: 打电话),传输效率低全双工通信(发送缓存 & 接收缓存),面向字节流.使用 TCP 的应用:web 浏览器;电子邮件,文件传输程序.
TCP是因特网中的传输层协议,使用三次握手协议建立连接.当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认.这种建立连接的方法可以防止产生错误的连接.[1]
TCP三次握手的过程如下:
客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态.
服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态.
客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态.
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了.
tcp 的三次握手
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的.
(1) 某个应用进程首先调用close,称该端执行"主动关闭"(active close).该端的TCP于是发送一个FIN分节,表示数据发送完毕.
(2) 接收到这个FIN的对端执行 "被动关闭"(passive close),这个FIN由TCP确认.
注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收.
(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字.这导致它的TCP也发送一个FIN.
(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN.[1]
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节.
注意:
(1) "通常"是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节.[2]
(2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为"半关闭"(half-close).
(3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN.
无论是客户还是服务器,任何一端都可以执行主动关闭.通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭.[2]
tcp 的四次挥手
UDP 协议
UDP--- 用户数据报协议,是一个简单的面向数据报的运输层协议.UDP 不提供可靠性,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地.由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快.
不可靠的,无连接的服务,传输效率高(发送前时延小),一对一,一对多,多对一,多对多,面向报文,尽最大努力服务,无拥塞控制.使用 UDP 的应用:域名系统 (DNS);视频流;IP 语音 (VoIP).
互联网协议按照功能不同分为 osi 七层或 tcp/ip 五层或 tcp/ip 四层
每层运行常见的物理设备
传输层--> 四层交换机,四层的路由器
网络层--> 路由器,三层交换机
数据链路层--> 网桥,以太网交换机,网卡
物理层--> 中继器,集线器,双绞线
每层运行常见的协议
应用层-->...
传输层-->TCP 与 UDP 协议
网络层-->ip 协议
数据链路层-->arp 协议
物理层-->...
三,socket
Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Socket 接口后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议.
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix 一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族的名字:AF_INET
(还有 AF_INET6 被用于 ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET 是使用最广泛的一个,python 支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用 AF_INET)
基于 TCP 协议的 socket
tcp 是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
conn.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
服务端
import socket
sk = socket.socket() # 创建客户套接字
sk.connect(('127.0.0.1',8898)) # 尝试连接服务器
sk.send(b'hello!')
ret = sk.recv(1024) # 对话(发送/接收)
print(ret)
sk.close() # 关闭客户套接字
客户端
来源: http://www.bubuko.com/infodetail-2474758.html