CSS Ribbon

Reproducing the GitHub Ribbon in CSS

路飞学城Python-Day23

1.计算机基础
Python可以实现各种应用软件,类比word、QQ、爱奇艺等,但是应用这些软件需要计算机硬件,
计算机发展的过程就是人类不断的希望机器去取代人力,解放更多的人力,最终极的理想就是完全像人脑一样完全取代人类去工作
编程语言就是机器能识别的表达方式,编程的结果就是程序(软件),硬件是固定的,如果需要硬件工作,就需要软件驱动
为什么需要操作系统?
软件就是驱动作用,那么不需要操作系统可以是实现么?也是可以的,但是开发的效率会非常低,因为需要考虑软件的实现,而且还要考虑机器的硬件的实现,工作量大,所以需要操作系统去实现根据程序操作硬件的具体调用
一个完整的计算机系统应该分为三层,这三层就是1.计算机应用(实现功能);2.操作系统(承上启下,把硬件的操作封装好后给应用程序调用);3.计算机硬件(具体执行程序的指令)
C/S架构
客户端Client
服务端Server

2.什么是网络
网络实际上就是为了互相通信使用的,要想基于网络通信,计算机与计算机之间需要联通,就是需要之间的物理连接介质要联通,
计算机与计算机之间的互相通信需要联网,需要底层的物理介质和通信的标准(互联网协议)
互联网协议就是计算机之间的英语,只要遵循标准去写,大家就都能实现通信,互联网协议被分为7层(或5层)

 


3.五层协议详解
什么是网络?
网络就是底层的物理连接介质加上互联网协议,互联网的协议就是计算机届的英语,但凡想要借助计算机通过互联网通信,都需要有互联网协议
互联网的5层协议

4.传输层详解
开发的是基于操作系统之上的应用软件,实际传输过程中就是将数据一步一步封装起来
协议的种类具体可以分为两类
1.应用层的自定义协议
2.应用层以下的规定的固定协议(TCP/UDP-IP-以太网)
TCP协议就是流式协议(stream),TCP协议发送数据就像是水流一样发送数据,客户端软件发送数据交给传输层(TCP)
数据是通过管道传输的,在没有数据传输的过程中就建立了数据传输管道(建立双向通道)
Tcp通过三次握手建立双向链接(第二次握手既有请求发送也有连接建立)
数据的传输是可靠的,对于Tcp建立好双向通道以后,发包一定要有确认信息,确实接收信息确认才会不再发信息
断开连接需要四次,四次挥手
Udp没有双向的通道存在,只负责传输数据,不负责检测信息的确认,Udp传输的数据是不可靠的
可靠性方面:TCP比UDP协议更可靠
效率方法:UDP效率更高(UDP开销低),TCP需要建立通道开销大

5.什么是socket
基于网络编程就是需要客户端和服务端,客户端和服务端都是工作于应用层,要是想要学会所有的协议是很困难的,于是就诞生了socket套接字: Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
套接字的发展史:套接字分为两种类型1. AF_UNIX;2. AF_INET
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族(使用这种类型)
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
套接字的工作流程
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

 


6.基于socket实现简单套接字通信
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
coon, client_addr = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
data = coon.recv(1024)
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
phone.send('hello'.encode('utf-8'))
data = phone.recv(1024)
print(data)
# 关闭
phone.close()

7.在简单套接字基础上加通信循环
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
while True:
coon, client_addr = phone.accept()
data = coon.recv(1024)
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data)
# 关闭
phone.close()
socket.send()实际上还是发给了自己的操作系统,操作系统再调用自己的网卡,应用程序来组织数据,操作系统操作TCP协议开始封装数据向下发包,软件的操作方式是应用级别的,操作系统完成应用层以下的4层封装打包
如果强行在client运行时关闭的话,在linux上服务端会一直循环,卡在recv接收处,windows则是直接报错

8.客户端与服务端代码bug修复
服务端可以并发的处理请求(没学到并发的情况下就是不断的循环),可以修改让服务端为客户端一个一个执行
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#可重复使用IP端口号
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
coon, client_addr = phone.accept()
while True:
try:
data = coon.recv(1024)
# if not data: break #linux上
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
except ConnectionResetError:
break
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
if not msg:
continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('utf-8'))
# 关闭
phone.close()

9.实现服务端可以对多个客户端提供服务
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#可重复使用IP端口号
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
while True:
coon, client_addr = phone.accept()
print(client_addr)
while True:
try:
data = coon.recv(1024)
# if not data: break #linux上
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
except ConnectionResetError:
break
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
if not msg:
continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('utf-8'))
# 关闭
phone.close()

10.模拟ssh远程执行命令-项目分析
ssh就是一个基于套接字写的客户端、服务端架构的软件
公司通常都是使用linux,有钱的用unix,没钱的使用centOS这样的服务器,windows的操作系统只是针对用户的体验使用的
 

11.模拟ssh远程执行命令-代码实现

12.粘包现象

13.粘包底层原理分析

14.解决粘包问题-伪代码实现

15.解决粘包问题-简单版本

16.解决粘包问题-终极版本

17.文件传输功能实现

18.文件传输功能-函数版

19.文件传输功能-面向对象版

20.基于udp协议的套接字介绍

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

posted on 2018-07-21 10:53  pandaboy1123  阅读(243)  评论(0编辑  收藏  举报

导航