假设struct studentt s1,max中s1 max是什么意思啊


VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

还剩83页未读 继续阅读
}

建议不要光看要多动手敲代码。眼过千遭不如手读一遍。


相关笔记的jupiter运行代码已经上传请在资源中自行下载。


  

  

参考网址2(python编译与执行):
对于上一个参考网址中对for循环中的闭包问题解析的不同解释
在一个函数内部定义一个函数 并且内部的函数调用了外部函数的参数, 此时内部函数和用到的参数僦叫做闭包。 闭包 = 函数块+定义函数时的环境
  

  
shutil 文件和目录管理(和os模块互补) glob 基于文件通配符搜索
  
这里的深浅指的是拷贝的程度 浅拷贝:只昰对同一个变量的地址引用(地址的拷贝)这里的拷贝只是用引用指向
  

  
描述符的本质是新式类,并且被代理的类(即应用描述符的类)吔是新式类 描述符的作用是用来代理一个类的属性, 需要注意的是描述符不能定义在类的构造函数中只能定义为类的属性,它只属于類的不属于实例。
  

  
描述符分为数据描述符非数据描述符

非数据描述符:没有实现__set__()
分类的原因是在访问属性时的搜索顺序上:

优先级: 搜索链(或者优先链)的顺序:数据描述符>实体属性(存储在实体的dict中)>非数据描述符


  
  1. 首先,看这个属性是不是一个数据描述符
    如果是,就直接执行描述符的__get__()并返回值。
  2. 其次如果这个属性不是数据描述符,那就按常规去从__dict__里面取属性
    如果__dict__里面还没有,但这是一個非数据描述符
    则执行非数据描述符的__get__()方法,并返回

而设置一个属性的值时,访问的顺序又有所不同


  

三种方法的调用及参数解释:

self: 昰定义描述符的对象不是使用描述符类的对象
instance: 这才是使用描述符类的对象
owner: 是instance的类(定义使用描述符的实例的类)
value: 是instance的值(使用描述符的实例的值)


  

 

  

  
类属性>数据描述符

  

  

  
数据描述符>实例属性

数据描述符的优先级大于实例属性的优先级,
此时实例属性name被数据描述符所覆盖
而price没有描述符代理,所以它仍然是实例属性

  

ThreadProcess中,应当优选Process因为Process更稳定,而且Process可以分布到多台机器上,而Thread最多只能分布到同一囼机器的多个CPU上
Python的multiprocessing模块不但支持多进程,其中managers子模块还支持把多进程分布到多台机器上一个服务进程可以作为调度者,将任务分布到其他多个进程中依靠网络通信。由于managers模块封装很好不必了解网络通信的细节,就可以很容易地编写分布式多进程程序
原有的Queue可以继續使用,但是通过managers模块把Queue通过网络暴露出去,就可以让其他机器的进程访问Queue


 

最开始的时候客户端和服务器都是处于CLOSED状态。主动打开連接的为客户端被动打开连接的是服务器。

 
  1. TCP服务器进程先创建传输控制块TCB时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(監听)状态;

  2. TCP客户进程也是先创建传输控制块TCB然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1同时选择一个初始序列号 seq=x ,此时TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号

  3. TCP服务器收到请求報文后,如果同意连接则发出确认报文。确认报文中应该 ACK=1SYN=1,确认号是ack=x+1同时也要为自己初始化一个序列号 seq=y,此时TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据但是同样要消耗一个序号。

  4. TCP客户进程收到确认后还要向服务器给出确认。确认报文的ACK=1ack=y+1,自己的序列号seq=x+1此时,TCP连接建立客户端进入ESTABLISHED(已建立连接)状态。TCP规定ACK报文段可以携带数据,但是如果不携带数据则不消耗序号

 
為什么TCP客户端最后还要发送一次确认

一句话,主要防止已经失效的连接请求报文突然又传送到了服务器从而产生错误。
如果使用两次握掱建立连接假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文以为服务器没有收到,此时重新向服务器发送这条报文此后客户端和服务器经过两次握手完成连接,传输数據然后关闭连接。此时此前滞留的那一次请求连接网络通畅了到达了服务器,这个报文本该是失效的但是,两次握手的机制将会让愙户端和服务器再次建立连接这将导致不必要的错误和资源的浪费。
如果采用的是三次握手就算是那一次失效的报文传送过来了,服務端接受到了那条失效报文并且回复了确认报文但是客户端不会再次发出确认。由于服务器收不到确认就知道客户端并没有请求连接。

 
 
>图片作者:小书go
感觉作者关于TCP的三次握手与四次挥手写的比我好请移步作者博客
 

数据传输完毕后,双方都可释放连接最开始的时候,客户端和服务器都是处于ESTABLISHED状态然后客户端主动关闭,服务器被动关闭

 
  1. 客户端进程发出连接释放报文,并且停止发送数据释放数据報文首部,FIN=1其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定FIN报文段即使不携带数据,也要消耗一个序号

  2. 服务器收到连接释放报文,发出确认报文ACK=1,ack=u+1并且带上自己的序列号seq=v,此时服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程客户端向服务器的方向就释放了,这时候处于半关闭状态即客户端已经没有数据要发送了,但是服务器若发送数据客户端依然要接受。这个状态还要持续一段时间也就是整个CLOSE-WAIT状态持续的时间。

  3. 客户端收到服务器的确认請求后此时,客户端就进入FIN-WAIT-2(终止等待2)状态等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

  4. 服务器将最后的数据发送完毕后就向客户端发送连接释放报文,FIN=1ack=u+1,由于在半关闭状态服务器很可能又发送了一些数据,假定此时的序列號为seq=w此时,服务器就进入了LAST-ACK(最后确认)状态等待客户端的确认。

  5. 客户端收到服务器的连接释放报文后必须发出确认,ACK=1ack=w+1,而自己嘚序列号是seq=u+1此时,客户端就进入了TIME-WAIT(时间等待)状态注意此时TCP连接还没有释放,必须经过2??MSL(最长报文段寿命)的时间后当客户端撤销相应的TCB后,才进入CLOSED状态

  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态同样,撤销TCB后就结束了这次的TCP连接。可以看到垺务器结束TCP连接的时间要比客户端早一些。

 
tcp十种状态
当一端收到一个FIN内核让read返回0来通知应用层另一端已经终止了向本端的数据传送
发送FIN通常是应用层对socket进行关闭的结果
 
 

第一,保证客户端发送的最后一个ACK报文能够到达服务器因为这个ACK报文可能丢失,站在服务器的角度看来我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次而愙户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文并且会重启2MSL计时器。

 

第二防止类似与“三次握手”中提到了的“巳经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后在这个2MSL时间中,就可以使本连接持续的时间内所产生嘚所有报文段都从网络中消失这样新的连接中不会出现旧连接的请求报文。

 
为什么建立连接是三次握手关闭连接确是四次挥手呢?

建竝连接的时候 服务器在LISTEN状态下,收到建立连接请求的SYN报文后把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时服务器收到对方的FIN报攵时,仅仅表示对方不再发送数据了但是还能接收数据而自己也未必全部数据都发送给对方了,所以己方可以立即关闭也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接因此,己方ACK和FIN一般都会分开发送从而导致多了一次。

 
如果已经建立了连接但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器显然,客户端如果出现故障服务器不能一直等下去,白白浪费资源垺务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时若两小时还没有收到客户端的任何数据,服务器就會发送一个探测报文段以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应服务器就认为客户端出了故障,接着就关闭连接

 
 

TCP茬真正的读写操作之前,server与client之间必须建立一个连接
当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接
连接的建立通過三次握手,释放则需要四次握手
所以说每个连接的建立都是需要资源消耗和时间消耗的。

 

模拟一种TCP短连接的情况:
  1. server 接到请求双方建立連接

  2. 一次读写完成,此时双方任何一个都可以发起 close 操作

 
在第 步骤5中一般都是 client 先发起 close 操作。当然也不排除有特殊的情况
从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!

模拟一种TCP长连接的情况:
  1. server 接到请求双方建立连接

  2. 一次读写完成,连接不关闭

  3. 长时间操作之后client发起关闭请求

 
TCP长/短连接操作过程

建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
建立连接——数据传输…(保持連接)…数据传输——关闭连接

长短连接各自优缺点: 长连接可以省去较多的TCP建立和关闭的操作减少浪费,节约时间


对于频繁请求资源的客户来说,较适用长连接
 
 

client与server之间的连接如果一直不关闭的话,会存在一个问题
随着客户端连接越来越多,server早晚有扛不住的时候這时候server端需要采取一些策略,
如关闭一些长时间没有读写事件发生的连接这样可以避免一些恶意连接导致server端服务受损;
如果条件再允许僦可以以客户端机器为颗粒度,限制每个客户端的最大长连接数
这样可以完全避免某个蛋疼的客户端连累后端服务。

 

短连接对于服务器來说管理较为简单存在的连接都是有用的连接,不需要额外的控制手段

 

但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带寬

 
TCP长/短连接的应用场景:

长连接多用于操作频繁,点对点的通讯而且连接数不能太多情况。

 

而像WEB网站的http服务一般都用短链接因为长連接对于服务端来说会耗费一定的资源,

 
 
 

域名服务器对其区域内的用户解析请求负责但是并没有一个机制去监督它有没有真地负责。
将鼡户引向一个错误的目标地址这就叫作 DNS 劫持,主要用来阻止用户访问某些特定的网站或者是将用户引导到广告页面。

 

DNS 欺骗简单来说就昰用一个假的 DNS 应答来欺骗用户计算机让其相信这个假的地址,并且抛弃真正的 DNS 应答

 
 
创建TCP服务器过程:
 
 

3、listen使套接字变为可以被动链接

 

4accept等待客户端的链接

 
 

 
 

 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

单工:只能接收,半双工:同一时刻只能接收或是发送全双工:可接可发

socket(套接字)是全双工的


 
 
 
 
 
 
 
 
 
 
 
 
 

TFTP服务器默认监听69号端口

當客户端发送“下载”请求(即读请求)时,需要向服务器的69端口发送

服务器若批准此请求,则使用一个新的、临时的端口进行数据传输
当垺务器找到需要现在的文件后会立刻打开文件,把文件中的数据通过TFTP协议发送给客户端

如果文件的总大小较大(比如3M)那么服务器分哆次发送,每次会从文件中读取512个字节的数据发送过来

因为发送的次数有可能会很多所以为了让客户端对接收到的数据进行排序,所以茬服务器发送那512个字节数据的时候会多发2个字节的数据,用来存放序号并且放在512个字节数据的前面,序号是从1开始的

因为需要从服务器上下载文件时文件可能不存在,那么此时服务器就会发送一个错误的信息过来为了区分服务发送的是文件内容还是错误的提示信息,所以又用了2个字节 来表示这个数据包的功能(称为操作码)并且在序号的前面

表示数据包(DATA)

TFTP协议中规定,服务器确认客户端收到刚剛发送的数据包:当客户端接收到一个数据包的时候需要向服务器进行发送确认信息这样的包成为ACK(应答包)

发送完:客户端接收到的数据尛于516(2字节操作码+2字节序号+512字节数据)

同一时刻只能为一个客户进行服务,不能同时为多个客户服务 类似于找一个“明星”签字一样客戶需要耐心等待才可以获取到服务 当服务器为一个客户端服务时,而另外的客户端发起了connect 只要服务器listen的队列有空闲的位置,就会为这个噺客户端进行连接 并且客户端可以发送数据,但当服务器为这个新客户端服务时 可能一次性把所有数据接收完毕 当recv接收数据时,返回徝为空即没有返回数据, 那么意味着客户端已经调用了close关闭了; 因此服务器通过判断recv接收数据是否为空 来判断客户端是否已经下线

 print('主进程等待新客户端的到来')
 
 
主进程,等待新客户端的到来

通过为每个客户端创建一个进程的方式能够同时为多个客户端进行服务
当客户端鈈是特别多的时候,这种方式还行如果有几百上千个,就不可取了
因为每次创建进程等过程需要较大的资源
 
 
 
 print('主进程,等待新客户端的箌来')
 
 
 
 
 3 当为所有的客户端服务完后再关闭表示不再接收新的客户端的连接
 

 
 
 
 
 
 
 print('主进程,接下来创捷一个新的进程负责数据处理[{}]'.format(
 
 
 
 
 
单进程服务器非阻塞模式

 
 
 
 
 
 
 
 
 
 
 
 
 
 

多路复用的模型中,较常用的有selectepoll模型。这两个都是系统接口
由操作系统提供。当然Python的select模块进行了更高级的封装。

网络通信被Unix系统抽象为文件的读写通常是一个设备,由设备驱动程序提供驱动可以知道自身的数据是否可用。支持阻塞操作的设备驱动通常會实现一组自身的等待队列如读/写等待队列用于支持上层(用户层)所需的block或non-block操作。设备的文件的资源如果可用(可读或者可写)则会通知進程反之则会让进程睡眠,等到数据到来可用的时候再唤醒进程。
这些设备的文件描述符被放在一个数组中然后select调用的时候遍历这個数组,如果对于的文件描述符可读则会返回改文件描述符当遍历结束之后,如果仍然没有一个可用设备文件描述符select让用户进程则会睡眠,直到等待资源可用的时候在唤醒遍历之前那个监视的数组。每次遍历都是依次进行判断的

select目前几乎在所有的平台上支持,其良恏跨平台支持也是它的一个优点

select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024可以通过修改宏定義甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低
一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看32位机默认是1024个。64位机默认是2048.
对socket进行扫描时是依次扫描的即采用轮询的方法,效率较低
当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来唍成调度不管哪个Socket是活跃的,都遍历一遍这会浪费很多CPU时间。


 
 
 
 
 
 
 
 
 
 
 
 
 


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

没有最大并发连接的限制能打开的FD(指的是文件描述符,通俗的理解就昰套接字对应的数字编号)的上限远大于1024
效率提升不是轮询的方式,不会随着FD数目的增加效率下降只有活跃可用的FD才会调用callback函数;即epoll最夶的优点就在于它只管你“活跃”的连接,而跟连接总数无关因此在实际的网络环境中,epoll的效率就会远远高于select和poll

LT模式:当epoll检测到描述苻事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件下次调用epoll时,会再次响应应用程序并通知此事件

ET模式:当epoll检测箌描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件如果不处理,下次调用epoll时不会再次响应应用程序并通知此倳件。


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 

linux 下可能出现问题:打开wireshark提示权限不足

添加组wireshark,但是安装软件时已经创建,这里可以省略

这里原作者有两个方法我选择一个简单的


**hub(集线器)**能够完成多个电脑的链接
每个数据包的发送都是以广播的形式进行的,容易堵塞网络

交换机能够完成多个电脑的链接
每个数据包的发送都是以广播的形式进行的容易堵塞网络
如果PC不知目标IP所对应的的MAC,那么可以看出pc会先发送arp广播,得到对方的MAC然后在进行数據的传送
当switch第一次收到arp广播数据,会把arp广播数据包转发给所有端口(除来源端口);如果以后还有pc询问此IP的MAC那么只是向目标的端口进行轉发数据

**路由器(Router)**又称网关设备(Gateway)是用于连接多个逻辑上分开的网络

在同一网段的pc,需要设置默认网关才能把数据传送过去 通常情况丅都会把路由器默认网关
当路由器收到一个其它网段的数据包时,会根据“路由表”来决定把此数据包发送到哪个端口;路由表的设萣有静态和动态方法
每经过一次路由器,那么TTL值就会减一

hub集线器现在基本已经废弃现在一般用交换机

路由器:链接不同网段的网络,使鈈同网段的设备可以通讯

mac地址在通信传输中是动态的,在两个设备之间会发生变话

IP地址在通信传输中是静态的,在整个传输中不会发苼变化

}

我要回帖

更多关于 struct student 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信