网络编程所有和并发编程,第四十九天

抱歉,纯英文了,以后想提升英文水平

SOCKET PROGRAMMING(Network Programming)
SOCKET PROGRAMMING(Network Programming) 1
1. 客户端/服务器架构 4
1.1. 硬件C/S架构(打印机) 4
1.2. 软件C/S架构(B/S架构) 4
1.2.1. server端必须满足的要求 5
1.3. C/S架构与socket的关系: 5
2. osi七层 5
2.1. 引子 5
2.1.1. 什么是互联网? 5
3. 网络基础之网络协议篇 5
3.1. 操作系统 5
3.2. 网络通信原理 6
3.2.1. 互联网的本质就是一系列的网络协议 6
3.2.1.1. 互联网协议(Internet Protocol Suite) 6
3.2.1.2. 互联网的两大要素 6
3.2.2. osi七层协议(只需掌握五层) 6
3.2.2.1. 每层运行常见的物理设备 7
3.2.2.2. 标识地址的方式 7
3.2.3. tcp/ip五层协议讲解 7
3.2.3.1. 物理层 7
3.2.3.2. 数据链路层 7
3.2.3.2.1. 以太网协议(ethernet) 7
3.2.3.2.2. mac地址 8
3.2.3.2.3. 广播 8
3.2.3.3. 网络层 8
3.2.3.3.1. IP协议 9
3.2.3.3.2. IP地址分成两部分 9
3.2.3.3.3. 子网掩码 9
3.2.3.3.4. IP数据包 9
3.2.3.3.5. ARP协议 9
3.2.3.4. 传输层 10
3.2.3.4.1. tcp协议 10
3.2.3.4.1.1. 建链接三次握手 10
3.2.3.4.1.1.1. 三次握手的过程解释 11
3.2.3.4.1.2. 断链接四次挥手 11
3.2.3.4.1.2.1. 四次挥手的过程解释 11
3.2.3.4.1.3. 半链接池 12
3.2.3.4.2. udp协议 12
3.2.3.5. 应用层 13
3.3. 发送数据和接收数据 13
3.4. URL统一资源定位器(Uniform Resource Locator) 13
3.5. www.xxx.xxx.的具体分析(根域、顶级域、二级域名) 14
4. socket层 14
5. socket是什么? 14
5.1. 扫盲 14
6. 套接字发展及分类 15
6.1. 基于文件类型的套接字家族(AF_UNIX) 15
6.2. 基于网络类型的套接字家族(AF_INET) 15
7. Socket Workflow 15
7.1. Socket Module Function Usage 15
7.2. Function of Server socket 16
7.3. Function of Client socket 16
7.4. General-purpose Socket Function 16
7.5. Lock-oriented Socket Method 17
7.6. A File-oriented Socket Function 17
8. Tcp Based Socket 17
8.1. TCP Server 17
8.2. TCP Client 18
8.3. Code of Server(links to cycle and communication to cycle) 18
8.4. Code of Client(links to cycle and communication to cycle) 18
8.5. Server Error(time_wait is still taking up the address) 19
8.5.1. Ending Method 1(use simpler) 19
8.5.2. Ending Method 2 19
8.6. Simulates ssh Remote Execution Command Version and Solve the Sticking Package Problem 20
8.6.1. Server 20
8.6.2. Client 21
8.7. Analysis of Stick Package Problems 22
8.7.1. Server 22
8.7.2. Client 23
9. Udp Based Socket 23
9.1. Use 23
9.2. Two Boundedness 23
9.3. Simple Example 23
9.3.1. Server 23
9.3.2. Client 24
10. Socketserver Module Implementation of Concurrent 24
10.1. Tcp Concurrent 24
10.1.1. Server 24
10.1.2. Client 25
10.2. Udp Concurrent 25
10.2.1. Server 25
10.2.2. Client 26




1.客户端/服务器架构
1.1.硬件C/S架构(打印机)


c是顾客customer,s是服务service。
1.2.软件C/S架构(B/S架构)


B/S架构也是C/S架构的一种,B是browser(浏览器)
client<---基于网络通信--->server




1.2.1.server端必须满足的要求


1、稳定运行(网络、硬件、操作系统、服务端应用软件),对外一直提供服务
2、服务端必须绑定一个固定的地址


1.3.C/S架构与socket的关系:


我们学习socket就是为了完成C/S架构的开发。


2.osi七层
2.1.引子


一个完整的计算机如果由硬件、操作系统、应用软件组成,有了这三个条件,一台计算机便可以和自己玩了(打个单机游戏)。但如果你想和别人一起玩,你就需要上网了。
2.1.1.什么是互联网?


互联网的核心就是一堆协议组成的,协议就是标准,比如全世界人通信的标准就是英语。如果把计算机比做人,互联网协议就是计算机界的英语。
所有的计算机都学会了互联网协议,那所有的计算机都可以按照统一的标准去收发信息从而完成通信了。
人们按照分工的不同把互联网协议从逻辑上划分了层次。


3.网络基础之网络协议篇
3.1.操作系统


操作系统(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。
注:计算机(硬件)-》os-》应用软件


3.2.网络通信原理
3.2.1.互联网的本质就是一系列的网络协议


一台设备有了操作系统,然后装上软件你就可以正常使用了,然而你也只能自己使用。像这样,每个人都拥有一台自己的机器,然而彼此孤立。因此我们可以把两台设备连接,并暂时将其定义为Internet。现在我们想象一个打电话的画面,如果我和你的语言不通,那么我们之间一定是无法沟通的,因此就有了
世界统一的通信标准——英语,可以看出Internet其实就是一套通信标准,这些标准称为互联网协议。


3.2.1.1.互联网协议(Internet Protocol Suite)


互联网协议其实就是一系列的协议,总称为互联网协议(Internet Protocol suite)。
互联网协议的功能:
定义计算机如何接入Internet,以及接入Internet的计算机通信的标准。


3.2.1.2.互联网的两大要素


1、底层的物理介质,是为通信铺好道路的
2、一套统一的通信标准


3.2.2.osi七层协议(只需掌握五层)


七层: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
五层:应用层 传输层 网络层 数据链路层 物理层
四层:应用层 传输层 网络层 数据处理层


3.2.2.1.每层运行常见的物理设备


传输层:四层交换机、四层的路由器
网络层:路由器、三层交换机
数据链路层:网桥、以太网交换机、网卡
物理层:中继器、集线器、双绞线
3.2.2.2.标识地址的方式


1、ip+mac:标识全世界独一无二的一台计算机
2、ip+mac+port:标识全世界独一无二的基于通信的应用软件
3、url地址:标识全世界独一无二的一个资源
3.2.3.tcp/ip五层协议讲解


我们把osi七层协议中的应用层、会话层、表示层统一并称为应用层.通过osi五层协议自下而上的讨论来了解互联网协议。osi五层协议中越往上的越靠近用户,越往下的越靠近硬件。


3.2.3.1.物理层


在两台设备之间基于某种介质为设备之间提供网络。
功能:
基于电器特性发送高低电压(电信号),高电压为1,低电压为0。


3.2.3.2.数据链路层


单纯的通过物理层传输0和1没有任何意义,因此必须得规定多少个0、1是一组,每一组代表什么信息。
功能:
定义了电信号的意义。


3.2.3.2.1.以太网协议(ethernet)


一组电信号构成一个数据报。叫做’帧‘。每一数据帧分为两部分,报头head和数据data两部分。
head包括18个字节:
源地址:6个字节
目标地址:6个字节
数据类型:6个字节
data最短46个字节,最长1500个字节。
每次发送数据最大限制字节数是1518字节,如若
超过该最大限制,便会分片发送。


3.2.3.2.2.mac地址


ethernet规定接入internet的每台设备都必须具备网卡,发送端和接收端的地址便是网卡地址,也称为mac地址。
mac地址:
每块网卡出厂时都被烧制了特有的mac地址,mac地址由48位二进制表示,12位十六进制表示。(前六位是厂商编号,后六位是流水线号)
3.2.3.2.3.广播


有了mac地址,通信设备之间便可以通信了(一台主机通过arp协议获取另一台主机的mac地址),ethernet采用最原始的方式,即广播的方式进行通信,所以计算机通信基本靠吼。在局域网内,如果一台计算机广播,局域网内的所有计算机都能接收到广播内容。


3.2.3.3.网络层


有了ethernet、 mac地址和广播,世界上所有的通信设备便可以进行同行了,但世界的互联网是由一个个小的局域网组成的,并且如果世界上的通信设备都用广播的方式进行通信,那么通信效率会大大降低,这将会称为一种灾难。因此得找到一种方式来区分哪些计算机属于同一广播域,哪些不是,如果是则用广播的方式发送,如果不是,则采用路由的方式(向不同广播域/子网分发数据包),mac地址是无法区分的,它只和厂商有关。
网络层功能:
引用一套新的地址来区分广播域/子网,这就是网络地址。


3.2.3.3.1.IP协议


规定网络地址的协议叫做ip协议,它定义的地址称为ip地址,广泛采用协议版本是的v4版本即ipv4,它规定网络地址是由32位二进制
表示。范围:0.0.0.0-255.255.255.255一个IP地址通常写成四段十进制数,例如:172.16.10.1


3.2.3.3.2.IP地址分成两部分


网络部分:标识子网
主机部分:标识主机
注意:单纯的ip地址字段只标识了ip的种类,从网络部份或主机部分都无法辨识一个ip所处的子网。


3.2.3.3.3.子网掩码


子网掩码,就是表示网络特征的一个参数。它在形式等同于IP地址,也是由一个32位的二进制数表示,但是他的网络部分都是1,主机部分都是0,即它的表示位255.255.255.0。我们可以通过把IP地址与子网掩码进行AND运算,如果比较结果相同
3.2.3.3.4.IP数据包


IP数据包也分为head和data两部分,Ip数据包直接放入以太网包的data内部。
head:20-60字节
data:最长位65515字节
注意:以太网的data最长长度是1500字节,如果IP的数据包超过1500字节,则需要
分割成几个以太网数据包
,分开发送了。
3.2.3.3.5.ARP协议


ARP协议由来:计算机通信基本靠吼,所有上层的包最后都要封装上以太网头,然而以太网传播需要知道源mac地址和目标mac地址,可是目标地址我们无法得知,因此就有了ARP协议。
ARP协议功能:
通过广播的形式,获得目标对象的mac地址。
协议工作方式:
每台主机的IP地址都是已知的。
1、通过IP地址和子网掩码区分自己所处的子网。
2、分析两台主机的IP地址是否在同一个网络(如果不存在那么下表中目标IP是网关Ip)
源mac 目标mac 源ip 目标ip 数据部分
发送端主机 发送端mac FF:FF:FF:FF:FF:FF 172.16.10.10/24 172.16.10.11/24 数据
3、这个包会以广播的形式传出,如果目标ip发现是自己的ip,则会返回mac地址。


3.2.3.4.传输层


网络层帮我们获取ip地址,以太网曾mac帮我们找到主机,然后大家使用的是应用程序,我们需要想办法找到对应的程序。而找到该应用程序的方法是端口,端口是应用程序和网卡关联的编号
传输层的功能:建立端口与端口的通信。
范围:端口范围:0-65535,0-1023为系统占用端口
3.2.3.4.1.tcp协议


可靠传输,tcp数据包没有长度限制,理论上可以无限长,但为了保证网络效率,一般不会超过ip数据包的长度,避免tcp数据包进行切割。
可靠的原因:它每发完一个数据包不会立即删除该数据包,他会等服务端返回一条已成功接收该数据包的信息再删除该数据包。
3.2.3.4.1.1.建链接三次握手


首先服务端处于监听状态,然后客户端发送一条请求syn和暗号seq=x,服务端收到请求和暗号开始响应,给客户端发送syn请求、暗号y和响应信号ack=x+1(1表示成功,0表示失败),客户端收到来自服务端的暗号并进行暗号与服务端发送的响应信号ack的对比,比对成功,成功建立客户端到服务端的数据传输路线。由于客户端和服务端双方都知道这一次请求只是为了给接下来的数据传输铺路,于是把本应该重来一次的请求再响应的两步步骤合并为一步,客户端直接返回响应信号ack=y+1,服务端收到响应信号与之前发送的暗号进行比对,比对成功,直接建立服务端到客户端的数据传输路线。
注意:如果一直有大量客户端发送syn请求,而没有大量建立服务端到客户端的数据传输路线,则很大程度表明有人在攻击服务端,用这个方法阻碍正常用户的syn请求进入。


3.2.3.4.1.1.1.三次握手的过程解释




3.2.3.4.1.2.断链接四次挥手


首先服务端成功传输了所有数据给客户端,然后开始发送一条关闭服务端到客户端的数据传输路线的请求fin,暗号seq=x+2,客户端接收到请求,响应并关闭了服务端到客户端的数据传输路线,并发送响应信号ack=x+3给服务端,服务端收到客户端发送的响应信号并与暗号进行比对,比对成功,得到服务端到客户端的数据传输路线已关闭的信息。等到客户端也成功传输了所有数据,客户端发送关闭客户端到服务端的数据传输路线的请求fin和暗号seq=y+1,服务端收到请求,发送响应信号ack=y+2给客户端,并关闭了客户端到服务端的数据传输路线,客户端收到响应信号ack并拿它与暗号进行比对,比对成功,得到客户端到服务端的数据传输路线以关闭的信息。
注意:因为fin_wait_1/2都是在很快的时间内完成的,而time_wait则会等待一段时间,如果time_wait等待的时间较长,则很大可能表明有很多用户在使用服务端。
3.2.3.4.1.2.1.四次挥手的过程解释




3.2.3.4.1.3.半链接池


由于建链接时,只能一条一条请求的来,有客户端对服务端发送了请求,下一条客户端请求就会显示等待。因此有了半链接池,他的工作原理是在客户端请求成功被服务端接收后,服务端不会马上对该请求发出响应,而是把这些请求存进半链接池内,只要半链接池没有满,客户端的请求都会进入服务端,如果半链接池满了,那么请求也会被阻拦在外面显示等待,并且半链接池会通过服务端响应最早进入的客户端请求,达到泄洪的目的。
注意:半链接池限制的同一时间的客户端请求数,而非连接数。


3.2.3.4.2.udp协议


不可靠传输,“报头”部分只有8个字节,总长度不超过65535个字节,正好可以放下一个ip数据包。
不可靠的原因:因为它不管服务端有没有成功接收数据包,它每发完一个数据包便会把这个发完的数据包删掉。
3.2.3.5.应用层


用户使用的都是应用程序,均工作于应用成,互联网是开发的,大家都开发自己的应用程序,因此必须得规定好应用程序的组织形式。
应用层功能:
规定应用程序的数据格式。
例:TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。
3.3.发送数据和接收数据


发送数据是封装的过程,而接收数据是解封的过程。


3.4.URL统一资源定位器(Uniform Resource Locator)


指的是一个url地址,该地址指向全球独一无二的计算机上的一个网页资源。开头http是一种应用层协议,由全球五大浏览器商家定义。中间www.xxx.xxx可以被电脑的DNS解析成目标对象的IP,一般www.xxx.xxx末尾还有.:80,.代表的是根域,:80代表的是80端口,www.xxx.xxx之后的是某个资源在服务端内具体的位置。
3.5.www.xxx.xxx.的具体分析(根域、顶级域、二级域名)


最后一个.代表根域,全球总共有13台根域服务器,美国九台,欧洲三台,日本一台,根域里默认存放着13台根域服务器的地址。
.前面的xxx是顶级域,中国的是cn。
.前面的xxx前面的xxx是二级域名,一般定位至具体的应用软件。
一般我们电脑打开一个网页的查找顺序根域-顶级域-二级域名。
中国没有根域,但用了根域缓存器来代替,它的工作原理是在我们每搜索一个网站时都会在根域缓存器里找,如果中国所有的根域缓存器都没有,那么才会去国外找,国外找到了根域缓存器辉保存这些资源。
中国根域缓存器查找方式有两种:递归查找,我没找到,我帮你问下一个根域缓存器;迭代查找,我没找到,我只告诉你可以在哪里找得到,你得自己找。
不是中国不弄根域服务端,因为根域服务端基于udp协议,udp协议一次性查找的字节太小,13个根域服务端的ip地址对udp协议能查找的字节而言就已经很大了,无法再放下一台根域服务器。
4.socket层


由于我们如果想构造一个C/S架构的软件,虽然可以自定义应用层协议,但是传输层协议却是固定的,tcp协议包含着很多东西,如果让我们去学习,是很浪费时间的一件事,因此及有人创建了一个socket库来帮我们解决tcp协议的事情,让我们只要用心与应用层便可以构造一个基于C/S架构的软件。
socket层介于应用层和传输层之间,它起着连接应用层和传输层的功能,同时它能连接应用层和网络层。
5.socket是什么?


socket是应用层和传输层之间通信的中间软件抽象层,它是一组接口。
socket把复杂的tcp/ip协议隐藏在socket接口后面,对用户来说,一组简单的接口就是全部,让socket组织数据,以符合指定的协议。
只要我们遵循socket的标准去编程,那么写出的程序自然是符合tcp/udp协议的。
5.1.扫盲


也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序
而程序的pid是同一台机器上不同进程或者线程的标识
6.套接字发展及分类
6.1.基于文件类型的套接字家族(AF_UNIX)


unix一切皆文件,基于文件的套接字调用的是底层的文件系统来获取数据,两个套接字进程运行在同一机器上, 可以通过访问同一个文件系统间接通信。
6.2.基于网络类型的套接字家族(AF_INET)


(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)。
7.Socket Workflow


先从服务端说起。服务端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接,在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
7.1.Socket Module Function Usage


1.import socket


2.socket.socket(socket_family,socket_type,protocal=0)


3.socket_family can be AF_UNIX or AF_INET. socket_type can be SOCK_STREAM or SOCK_DGRAM.
 protocal generally the default is 0.


4.Get tcp/ip socket
tcpSock  = socket.socket(socket.AF_INET,socket.socket.SOCK_STREAM)


6.Get udp/ip socket
udpSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)


7.Beacause socket module have too much attribute.
We use exception 'from module import *' statement. Use 'from socket import *', we can bring the attribute of socket module to our namespace, it can drastically reduce our codes.


8.E.g:tcpSock = socket(AF_INET, SOCK_STREAM)
7.2.Function of Server socket


s.bind() Binding (Host, Port) to socket.
s.listen() Strating TCP listening.
s.accept() Passively accept connections from TCP client.


7.3.Function of Client socket


s.connect() Actively initialize the TCP service connection.
s.connetct_ex() Extended version of the connection function, return error code when an error occurs, instead of throwing a exception.
7.4.General-purpose Socket Function


s.recv() ReceiveTCP data.


s.send() Send TCP data(When the amount of data to be sent is greater than the remaining space in the end cache area, the data is lost and 
will not be send out.


s.sendall() Send complete data(The essence is to call send in a loop. Sendall does not lose the data when the amount of data to be sent is greater than the rest of the cache on its own side, and calls send in a loop until it is finished.


s.recvfrom() Receive UDP data.


s.sendto() Send UDP data.


s.getpeername() Connect the address at the far end of the current socket.


s.getsockname() Get the address of current socket.


s.getsockopt() Returns the parameters for the specified socket.


.s.setsockopt() Sets the parameters for the specified socket. 


s.close() Close socket.
7.5.Lock-oriented Socket Method


s.setblocking() Sets the blocking and non-blocking modes of the socket.


s.settimeout() Sets the timeout for blocking socket operations.


s.gettimeout() Get the timeout for blocking socket operations.




7.6.A File-oriented Socket Function


s.fileno() The file descriptor for the socket.


s.makefile() Sets a file relate to socket. 
8.Tcp Based Socket


TCP is based on link, and you must start the server first, and then start the client to connect to the server.
8.1.TCP Server


ss = socket() # Sets a server socket.
ss.bind() # Bind the address to the socket.
ss.listen() # Listening to the link.
inf_loop: # Server infinite loop.
cs = ss.accept # Accept client link.
comm_loop: # Communication cycle.
cs.recv()/cs.send() # dialogue(receive or send)
cs.close() # Close client socket.
ss.close() # Close server socket(choosable)
8.2.TCP Client


cs = socket() # Sets client socket.
cs.connect() # Try to connect to the server.
comm_loop: # Communication loop
cs.send()/cs.recv() # Dialogue(receive or send)
cs.close() # Close client socket.
8.3.Code of Server(links to cycle and communication to cycle)


import socket


ip_port = ('127.0.0.1', 8080)
BUFSIZE = 1024


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(ip_port)
s.listen(5)


while True:
conn, addr = s.accept()
print('Receive %s's phone'%addr[0])
while True:
msg = conn.recv(BUFSIZE)
if len(msg) == 0: break
conn.send(msg.upper())
conn.close()


s.close()
8.4.Code of Client(links to cycle and communication to cycle)


import socket


ip_port('127.0.0.1', 8080)
BUFSIZE = 1024


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect_ex(ip_port)


while True:
msg = input(">>>").strip()
if len(msg) == 0: continue
s.send(msg.encode('utf8'))
feedback = s.recv(BUFSIZE)
print(feedback.decode('utf8'))


s.close()
8.5.Server Error(time_wait is still taking up the address) 




This is because your server is still four times to wave the time_wait state in the occupied address (if you don't understand, please study 1. TCP three-way handshake, wave four times 2. The syn flood attack 3. High concurrency server cases there will be a lot of time_wait state optimization method)
8.5.1.Ending Method 1(use simpler)


# Add a socket configuration and reuse the IP and por


phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR# is it, before binding
phone.bind(('127.0.0.1',8080))
8.5.2.Ending Method 2


 # Finding a large number of TIME_WAIT state connections in the system, by adjusting the Linux kernel parameters.


vi /etc/sysctl.conf


 # Edit the file and add the following:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
 
# Then execute /sbin/ sysctl-p for the parameter to take effect.
 
net.ipv4.tcp_syncookies = 1 #Means open SYN Cookies。When SYN waits for queue overflow, enable cookies to handle it, which can prevent a small number of SYN attacks. The default is 0, indicating close.


net.ipv4.tcp_tw_reuse = 1 # Represents opening reuse.Time-wait sockets are allowed to be reused for new TCP connections, with default of 0, indicating off.


net.ipv4.tcp_tw_recycle = 1 # Represents a quick recovery of time-wait sockets in TCP connections, which is enabled by default to 0.


net.ipv4.tcp_fin_timeout # Modify the system's default TIMEOUT time.
8.6.Simulates ssh Remote Execution Command Version and Solve the Sticking Package Problem
8.6.1.Server


from socket import *
import subprocess
import struct
import json


server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)


while True:
    conn, client_addr = server.accept()
    print('新的客户端', client_addr)
    while True:
        try:
            cmd = conn.recv(1024)
            if len(cmd) == 0: break
            obj = subprocess.Popen(
                cmd.decode('utf8'),
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()


            header_dic = {
                'filename': 'a.txt',
                'total_size': len(stderr + stdout),
                'filetype': 'video',
            }
            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode('utf8')
            conn.send(struct.pack('i', len(header_bytes)))
            conn.send(header_bytes)
            conn.send(stderr + stdout)


        except ConnectionResetError:
            break
    conn.close()
8.6.2.Client


from socket import *
import struct
import json


client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
while True:
    cmd = input(">>>cmd:").strip()
    if len(cmd) == 0: break
    client.send(cmd.encode('utf8'))
    header_len = struct.unpack('i', client.recv(4))[0]
    header_bytes = client.recv(header_len)
    header_json = header_bytes.decode('utf8')
    header_dic = json.loads(header_json)
    print(header_dic)
    total_size = header_dic['total_size']
    receive_size = 0
    res = b''
    while receive_size < total_size:
        data = client.recv(1024)
        res += data
        receive_size += len(data)
    print(res.decode('gbk'))
client.close()
8.7.Analysis of Stick Package Problems


There are three ways to solve stick package problem.
First: You can set a timeout when you send per message at client.


Second: You can send a message to client, if client receive this message, client will send anther message to tell server it have ready to receive data, and then server send data.


Third: You can set a header and fixed header length, through a series of operation to sovele this problem.(see details-Simulates ssh Remote Execution Command Version and Solve the Sticking Package Problem)


8.7.1.Server


from socket import *


server = socket()
server.bind(('127.0.0.1', 8080)
server.listen(5)
conn, adrr = server.accept()


res1 = conn.recv(1024)
conn.send('第一次', res1)


res2 = conn.recv(1024)
conn.send('第二次”,res2)


res3 = conn.recv(1024)
conn.send('第三次”,res3)
8.7.2.Client


from socket import *


client = socket()
client.connect(('127.0.0.1', 8080))


client.send(b'hello')
client.send(b'world')
client.send(b'cyd')
9.Udp Based Socket


UDP protocol is User Datagram Protocol, it can send header when it send data, and it unlike TCP protocol need to set connect . 
The information received by the server is a tuple, the tuple contained the message send by client and the address of client. 
UDP has no sticking problem, because of it receives one piece of data for every piece of data it sends. It has two separate ends, neither of which will cause the other end to collapse.
9.1.Use


Because udp only can receive 512 bytes, so it's usually used to query some kind of data and qq chat and so on.
9.2.Two Boundedness


UDP protocol can implementation of concurrent , but the concurrent has two boundedness:
first,customers is too much, 
second, file data is too large 
9.3.Simple Example
9.3.1.Server


from socket import *


server = socket(AF_INET, SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))


while True:
data, client_address = server.recvfrom(1024)
server.sendto(data.upper(), client_address)


server.close()
9.3.2.Client


from socket import *


client = sockek(AF_INET, SOCK_DGRAM)


while True:
msg = input(">>>msg: ").strip()
client.sendto((msg.encode('utf8'), '127.0.0.1', 8080))
data = client.recvfrom(1024)
print(data[0])


client.close()

10.Socketserver Module Implementation of Concurrent


We couldn't merge the communication cycle with the connection cycle before, so we couldn't do concurrency.
Here we can achieve concurrency through module socketserver.


10.1.Tcp Concurrent
10.1.1.Server


import socketserver


class Myhandle(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
data = self.request.recv(1024)
if len(data) == 0: break
self.request.send(data.upper())
except ConnectionResetError:
break
self.request.close()


if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), Myhandle)
server.serve_forever()
10.1.2.Client


from socket import *


client = socket()
client.connect(('127.0.0.1', 8080))


while True:
msg = input(">>>msg:").strip()
if len(msg) == 0: continue
client.send(msg.encode('utf8'))
data = client.recv(1024)
print(data.decode('gbk'))
client.close()
10.2.Udp Concurrent
10.2.1.Server


import socketserver




class Myhandle(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            data = self.request[0]
            self.request[1].sendto(data.upper(), self.client_address)
        self.request.close()




if __name__ == '__main__':
    server = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), Myhandle)
    server.serve_forever()


10.2.2.Client


from socket import *


client = socket(AF_INET, SOCK_DGRAM)
while True:
msg = input(">>>msg:").strip()
client.sendto(msg.encode('utf8'), ('127.0.0.1', 8080))
data = client.recvfrom(1024)
print(data[0])


client.close()

CONCURRENT PROGRAMMING
CONCURRENT PROGRAMMING 1
1. Process Management 2
1.1. What is process 2
1.2. Why use the process 2
1.3. How to use the process 2
1.3.1. Concurrence 2
1.3.2. Parallel 2
2. Operating System Introduction 2
2.1. Mutil-channel technology 2
2.1.1. Spatial reuse 3
2.1.2. Time reuse 3
2.2. Serial(串行) 3
2.3. concurrence 3
2.4. Parallel 3
2.5. Function of Cpu 3




1.Process Management
1.1.What is process 


It refers to a running program or a running process of the program, which is an abstract concept.
1.2.Why use the process


The program is dead, the process is alive.
1.3.How to use the process
1.3.1.Concurrence


Concurrence is a pseudo(伪) parallel, it looks like multitasking.  Cpu and multi-channel technologies can be implemented.
1.3.2.Parallel


The real multitasking runs simultaneously, only multiple cpus can be implemented.
2.Operating System Introduction



2.1.Mutil-channel technology


cpu encountered I/O operation switching, it increases efficiency.


A process that takes up too much CPU time also switches,In order to achieve the concurrency effect, it will reduce the efficiency of the program.
2.1.1.Spatial reuse


Mutiple processes share one memory bar,
2.1.2.Time reuse


Multiple processes reuse the same CPU time.
2.2.Serial(串行)


Only after a task has been completed can the next task be run.
2.3.concurrence


It seems that multiple tasks can run at the same time, and a single core can achieve concurrency.
2.4.Parallel


In a real sense, multiple tasks are running simultaneously, and only multi-core can achieve parallel
2.5.Function of Cpu


The CPU is used for calculation, and the CPU cannot perform IO operations. Once an IO operation is encountered, the CPU should be allowed to perform other tasks.

如果你能看完,再说句抱歉,个人私心,也谢谢你的观看。

猜你喜欢

转载自blog.csdn.net/weixin_42157426/article/details/80991182