#架构
C/S架构(鼻祖)
c:client 客户端
s:server 服务器
B/S架构(隶属于C/S架构)B/S架构的优点:统一了应用的入口(是一个趋势)
b:browser 浏览器
s: server 服务器
软件开发的架构:
1.C/S架构
C/S即:Client与Server ,中文意思:客户端与服务器端架构,这种架构也是从用户层面(也可以是物理层面)来划分的。
这里的客户端一般泛指客户端应用程序EXE,程序需要先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖较大。
2.B/S架构
B/S即:Browser与Server,中文意思:浏览器端与服务器端架构,这种架构是从用户层面来划分的。
Browser浏览器,其实也是一种Client客户端,只是这个客户端不需要大家去安装什么应用程序,只需在浏览器上通过HTTP请求服务器端相关的资源(网页资源),客户端Browser浏览器就能进行增删改查。
网络基础
#两个电脑如何通信:一根网线
网卡有个mac地址,又叫做物理地址,查看mac地址命令: ipconfig -all (查看以太网,物理地址)
几十台电脑如何通信:局域网:通过交换机实现
怎样知道一个局域网里有多少台电脑:同一个局域网里有相同的网段
网段:192.168.12.XX(前三个在同一局域网中相同,而XX范围是0-255,所以一个网段最多能放256台电脑)
IP地址:是一个四位十进制分开的一串数字。
子网掩码:是计算机根据你的IP地址生成的一个东西
网段:ip地址 &子网掩码
例如:IP地址:192.168.12.84(将84=64+20=64+16+4->转换成二进制01010100)
二进制:11000000.10101000.00001100.01010100
子网掩码:255.255.255.0
子网掩码:1111111.11111111.11111111.00000000
与操作:11000000.10101000.00001100.01010100
11111111. 11111111. 11111111. 00000000
--------------------------------------------------------
11000000.10101000.00001100.00000000
192.168.12.0:得到网段
2进制的算法:
路由器:有一个路由表,用来记录网段信息。
交换机通信:
广播:吼一嗓子
单播:方向固定的向某一个主机发送
组播:朝某一部分或某一组主机发送
更多电脑之间的通信:
广域网 交换机+路由器+代理IP
tcp和udp协议都是基于socket模块。两种协议可以混着用。
tcp:会慢一点,安全可靠,面向连接,字节流服务--代表没有边界
udp:不安全不可靠,不面向连接,但是效率高(大部分视频会议用udp) (干完就 跑)面向数据表连接
端口:
ip + prot 唯一确定一台主机上的某一个程序(你打开一个程序就有一个端口)
允许开发人员使用的端口号范围从8000开始 8000-10000(每开启一个程序,会随机得到个端口号)
TCP协议
当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。
这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。
TCP是面向连接的
三次握手:
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协议
相对TCP协议而言,UDP协议
当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立连接。
当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上
cp和udp的对比
TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
互联网协议与osi模型
互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层
每层运行常见物理设备
每层运行常见的协议
理解各层作用:
socket概念
socket层
理解socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
其实站在你的角度上看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。 所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。
套接字的发展史:
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
socket参数的详解
socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)
创建socket对象的参数说明:
面试题:
真实的:
1、你知道哪些研发相关的架构?
2、arp协议做了什么事情?:通过IP地址找到对应的mac地址。
3、交换机的通讯方式?
4、你认为tcp和udp的区别?
5、请描述出osi五层模型?
我出的:
1、网段ip怎么确定?
2、请描述B/S架构的优势
**********************************************************
双全工:是指,两端一旦建立连接之后,谁给谁先发消息都可以
tcp与udp区别
tcp协议,不允许在同一时间点同时和多个客户端连接通信
udp协议,允许在同一个时间点同时和多个客户端连接通信
tcp协议编码中,服务器是可以先和客户端通信的
udp协议编码中,服务器必选先接受客户端的消息,才能知道客户端的地址
在一台电脑上通过py文件手动通信-tcp
#服务器 import socket sk = socket.socket()#我买一个手机 sk.bind(('127.0.0.1',8090))#买一个电话卡 sk.listen(5)#告诉了几个人我的手机号 #print(123) fd,addr = sk.accept()#等着别人给打电话,阻塞等待客户端来连接, #print(456) #print(fd,addr) #通过fd就能给客户端发送信息了 #打印出<socket.socket fd=164, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, # laddr=('127.0.0.1', 8090), raddr=('127.0.0.1', 58613)> ('127.0.0.1', 58613)#这里是客户端的地址,客户端的信息 #通话 while 1: msg_r = fd.recv(1024).decode('utf-8') print(msg_r) if msg_r == 'q': break msg_s = input('>>>') fd.send(msg_s.encode('utf-8')) if msg_s == 'q': break fd.close() #挂断电话 sk.close()#关机
import socket sk = socket.socket() sk.connect(('127.0.0.1',8090)) #收发信息的逻辑 while 1: msg_s = input('>>>') sk.send(msg_s.encode('utf-8')) if msg_s == 'q': break msg_r = sk.recv(1024).decode('utf-8') print(msg_r) if msg_r == 'q': break sk.close()
如何一个服务器连接多个客户端-tcp
import socket #创建tcp socket的套接字 sk = socket.socket() #bind sk.bind(('127.0.0.1',8080))#8080代表http #监听 sk.listen(5) while 1: #等待连接 conn,adder =sk.accept() while 1: msg_s = input('>>>') conn.send(msg_s.encode('utf-8')) if msg_s == 'q': break msg_r = conn.recv(1024).decode('utf-8') if msg_r == 'q': break print(msg_r) conn.close() sk.close()
import socket sk = socket.socket() sk.connect(('127.0.0.1',8080))#有个返回值 while 1: msg_r = sk.recv(1024).decode('utf-8') if msg_r == 'q': break print(msg_r) msg_s = input('>>>') sk.send(msg_s.encode('utf-8')) if msg_r == 'q': break sk.close()
udp通信:
import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8090)) while 1 : msg_r,addr = sk.recvfrom(1024) print('接受到来自%s地址的一条消息:%s'%(addr,msg_r.decode('utf-8')))#这里可以 msg_s =input('>>>').encode('utf-8') sk.sendto(msg_s,addr) sk.close()
import socket sk=socket.socket(type=socket.SOCK_DGRAM) while 1: msg_s = input('>>>').encode('utf-8') sk.sendto(msg_s,('127.0.0.1',8090)) msg_r,addr = sk.recvfrom(1024) print(msg_r.decode('utf-8'),addr) sk.close()
udp通信控制台带颜色输出
import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8090)) dic = {'小白':'