开发的第二阶段 网络编程阶段
之所以叫网络编程,是因为,这里面就不是你在一台机器中玩了.多台机器,CS架构.即客户端和服务器端通过网络进行通信的编程了.
首先想实现网络的通信,你得先学网络通信的一个基础,即两台机器之间是怎么打通的.有的同学说机器有IP地址,能互相ping通就连上了.
7层网络协议,第三层:网络层,第四层,传输层(tcp/ip协议).tcp/ip协议保证了两台机器的通信的可靠的数据传输(tcp/ip协议通信的3次握手).什么叫可靠的. A给B发消息,A发了,A会知道发没发到.
UDP不是可靠的数据传输协议,当A给B发消息,A发送出去了,A不知道B收没收到.A也不管.
UDP依然在使用.因为它快.
tcp/ip传输协议在发送数据前进行建立链接的3次握手.
3次握手后,才进行真正发送数据.那么问题来了.是什么东西在负责发送数据,对方又是什么东西在进行数据接收呢.那就是socket.
socket可以简单直白的认为它是一个管道,具体你在管道里传输什么socket不关心,如:mysql,http,这些对于socket来说就是一辆车. Socket 基础 socket 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求.
socket起源于Unix,而Unix/Linux 基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.
socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO\打开\关闭)
socket和file的区别:
file模块是针对某个指定文件进行[打开][读写][关闭]
socket 模块是针对 服务器端 和 客户端socket 进行 [打开][读写][关闭] socket基础使用实例:
socket_server.py
  import socket
        ip_port = ('127.0.0.1',9999)      
sk = socket.socket()        #创建一个socket的句柄,如同open()一个文件
sk.bind(ip_port)            #使用bind()方法,向系统内核注册一个ip,端口 作为这个socket的ip,port的属性,如果此端口没被占用,则
返回含有ip和端口的句柄,如果被占用则报错退出程序
sk.listen(5)               #这个socket句柄处于监听状态。 while True:                #写一个死循环,用来接收客户端对socket的链接请求
print('server waiting ......') conn,addr = sk.accept()       
       #程序执行到accept()时,阻塞在这里,当客户端使用connect()方法,发送连接请求,accept()方法把客户端的ip也就是addr作为参数,传入sk这个socket实例设置了客户端的ip端口属性,然后把返回实例的内存地址,赋值给新的变量conn。语法就是conn,addr = 实例名.accept()。
client_data = conn.recv(1024)   #客户端和服务端的连接成功后,socket生成,紧接着在这里调用recv()方法,程序继续阻塞,直到客户端调用send方法,conn.recv(1024) 中的1024指的是一次最大接收1024个字节。
print(str(client_data,'utf8'))
conn.send(bytes("不要回答,不要回答",'utf8')) #服务端发送即对socket套接字进行写操作。 conn.close()

socket_clinet.py

  import socket
  ip_port = ('127.0.0.1',9999)
  sk = socket.socket()
  sk.connect(ip_port)
  
  sk.sendall(bytes("请求占领地球",'utf8'))   server_reply = sk.recv(1024)
  print(str(server_reply,'utf8'))
  sk.close()

基本的socket用法,很简单就实现了。那么我们深入一些:

1.能不能让客户端和服务端进行通信呢?

2.这是一个客户端,连接这个服务端。当多个客户端连接这个服务端会怎样?(这个测试下来,这种基本的socket是不能多个客户端访问的。)

那么我们来尝试解决问题1.

socket_server02.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.send(bytes("不要回答,不要回答",'utf8'))
while True:
client_data = conn.recv(1024)
print(str(client_data,'utf8')) server_response = input(">>>")
conn.send(bytes(server_response,'utf8'))
conn.close()

socket_clinet02.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) sk.sendall(bytes("请求占领地球",'utf8')) server_reply = sk.recv(1024)
print(str(server_reply,'utf8'))
while True:
user_input = input(">>>:").strip()
sk.send(bytes(user_input,'utf8'))
server_reply = sk.recv(1024)
print(str(server_reply,'utf8'))
sk.close()

先执行socket_server02.py

在执行socket_client02.py,执行结果如下:

socket_client02.py
不要回答,不要回答     #接到服务器的第一个响应
>>>:dd          #客户端输入dd
你大爷            #哟,服务端骂人
>>>:龟孙            #骂回去
日你先人          #服务器又骂回来一句
>>>: socket_server02.py
server waiting ......
请求占领地球 #接到的第一个clinet send
dd        #服务端收到dd
>>>你大爷     #服务端回复,d d看不懂,就说了句“你大爷”
龟孙        #乖乖,敢回嘴,我可是服务器
>>>日你先人    #接着骂

那么我这上面都是正常通信,输入的字符串都是正常的,假如客户端不输入了,直接退出。会怎样?

这里就不赘述老师的试验过程了,最终结果,老师说当clinet客户端停掉,windows和Linux的服务端对这个异常处理的方式不一样

但我自己在mac和Linux下尝试的结果一样,判断接收到clinet_data数据是否为空,为空就跳出循环。

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.send(bytes("不要回答,不要回答",'utf8'))
while True: client_data = conn.recv(1024)
if not client_data:break #判断当,对方传过来的值为空时,直接退出
print('client_data',str(client_data,'utf8')) server_response = input(">>>")
conn.send(bytes(server_response,'utf8')) conn.close()

windows下,当客户端停掉,server端 conn.recv(1024)得到的数据不是空值,而是异常,异常发生后,程序就会退出,所以这里就要用到异常处理方法try语法,具体代码如下:这段代码如果用到Linux中,将无限循环下去,因为客户端停掉后,服务端会认为conn.recv(1024)得到空值,这样无限循环下去。

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.send(bytes("不要回答,不要回答",'utf8'))
while True:
try:
client_data = conn.recv(1024)
print('client_data',str(client_data,'utf8'))
except Exception:
print("clinet closed,break")
break
server_response = input(">>>")
conn.send(bytes(server_response,'utf8')) conn.close()

使用socket写一个远程的ssh工具:

04socket_server.py代码如下:

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习,做成可以远程输入命令,客户端获得输出结果,如果你的命令输出结果很多,那么客户端得到的结
'''
import socket
import subprocess
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() # client_data = conn.recv(1024)
# print(str(client_data,'utf8'))
# conn.send(bytes("不要回答,不要回答",'utf8'))
while True:
print("客户端{}已经连接,等待客户端传输命令... ...".format(conn.getpeername()))
client_cmd_re = conn.recv(1024)
if not client_cmd_re:break # 判断当,对方传过来的值为空时,直接退出(在客户端我已经判断用户输入不能为空,所以这里为空,只有一种可能,就是客户端关闭程序了.如果没有这句的break,会导致客户端一旦关闭,服务端也跟着关闭.
# 因为当客户端关闭后,传过来的不知道是什么东西)
print("用户传来了命令:%s"%client_cmd_re) # 打印输出用户传来的命令
cmd_re_str = str(client_cmd_re,'utf8') # 将用户传来的命令转换成str # 将命令执行,并获得执行结果
cmd_exec_result = subprocess.Popen(cmd_re_str,shell=True,stdout=subprocess.PIPE).stdout.read()
# print(cmd_exec_result) # 打印执行的结果
# print(len(cmd_exec_result)) # 打印结果的长度
if len(cmd_exec_result) == 0 : # 判断结果是不是为空,为空说明用户传过来的命令,本服务器无法执行.
cmd_exec_result = bytes("命令 '{}' 后没有返回执行结果,请检查命令是否正确...".format(cmd_re_str),'utf8') # 提示命令不对
#将执行结果发送给客户端
conn.send(cmd_exec_result)
conn.close()

04socket_client.py代码如下:

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) # sk.sendall(bytes("请求占领地球",'utf8'))
#
# server_reply = sk.recv(1024)
# print(str(server_reply,'utf8'))
while True:
input_cmd = input("cmd:").strip() # 用户输入命令
if input_cmd == 'q':break # 用户如果输入的是q,退出输入命令的循环
if not input_cmd:continue # 用户如果直接按了回车,既为空,则进行下次循环
print(input_cmd) # 打印此次用户输入的命令
sk.send(bytes(input_cmd,'utf8')) # 将用户的命令通过socket发送给服务器端
cmd_exec_data = sk.recv(1024) # 接收服务器执行命令后返回的结果
print(str(cmd_exec_data,'utf8'))
sk.close()

上面的代码已经实现了,client连接到server后,进行基本的简单的命令。却不能进行实时的交互,比如top,cd 这种执行后没法返回的命令。具体如何时间,第七天的课程暂不说明。

那么问题来了,client端在接收设置中用到了sk.recv(1024),设置了每次最大收1024个字节,当你执行一个ifconfig命令,字节将大于1024,客户端就会一次收不完,这些数据,会怎样。这些数据已经被服务端通过socket发送过来了。你再次调用sk.recv(1024)时,继续接收余下的数据。那么怎样才能继续接收呢?目前的代码是循环到下次输入命令时会接收ifconfig命令结果的后续。那它这次的命令就又要排队到后面了。

那么如何进行循环接收呢?当然是在本次执行命令中,在sk.recv(1024)代码前加while 循环。

问题又来了。默认是死循环,while True,那么本次命令循环接收sk.recv(1024)结束条件怎么设置呢。

先说明:这里处理方法只有一种,就是在服务端传给客户端字符串前,先把传输的字节数告诉客户端。客户端循环接收字节,并把接收到的字节数累加统计,然后拿接收到的字节总数和服务端发来的做比较。如果小于继续循环。

但是: 老师给我们理清了思路,尝试了3种测试的方法,通过这3次尝试,让我们渐渐的了解socket传输的内部原理。

尝试方案1:

  客户端在接收调用sk.recv(1024)方法,我们可以尝试调大这个数值,看看结果。是可以,每次多收一些,但是,如果你一个字符串有100*1024bytes,你不能把接收数值调整到100M吧,那内存还不爆掉。并且socket官方建议最大不能超过8192,所以此方案不可行。并且一般设置500即可。

尝试方案2:

   我们在接收哪里直接while True,一直接收,直到接收不到数据时就退出break

  06socket_server.py 不需要改动

  06socket_client.py 代码如下:

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
当服务端发送过来的字符串字节数过大,一次接收不完,客户端通过判断服务器端是不是发送完,来作为循环接收的依据。
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) # sk.sendall(bytes("请求占领地球",'utf8'))
#
# server_reply = sk.recv(1024)
# print(str(server_reply,'utf8'))
while True:
input_cmd = input("cmd:").strip() # 用户输入命令
if input_cmd == 'q':break # 用户如果输入的是q,退出输入命令的循环
if not input_cmd:continue # 用户如果直接按了回车,既为空,则进行下次循环
print(input_cmd) # 打印此次用户输入的命令
sk.send(bytes(input_cmd,'utf8')) # 将用户的命令通过socket发送给服务器端 res = bytes('','utf8')
while True:
cmd_exec_data = sk.recv(500) # 接收服务器执行命令后返回的结果
res += cmd_exec_data
if not cmd_exec_data :            #这里判断,当接收不到数据时,就退出循环
break
print(str(res,'utf8'))
sk.close()

ps:此方式不可行。原因是cmd_exec_data = sk.recv(500) 这里在接收完本次命令执行的所有结果后,会一直阻塞在这里。不会退出循环,此时客户端就卡死了。

总结:sk.recv()和sk.send()都会阻塞

尝试方案3:

  在客户端判断服务端的数据是不是传完了,如果没传完,则继续循环接收。

  05scoket_server.py 不需要改动

  05socket_client.py 代码如下:

  

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
当服务端发送过来的字符串字节数过大,一次接收不完,客户端通过判断服务器端是不是发送完,来作为循环接收的依据.
如何判断服务器端是不是发送完成?
我们认为,客户端每次接收的最大值500字节.那么如果最后一次传过来的数据长度没有500字节,那么我们是不是就可以说这次就是最后一次传输来.
所以while 循环中判断接收到的数据长度小于500,就退出循环接收.
代码如下:
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) # sk.sendall(bytes("请求占领地球",'utf8'))
#
# server_reply = sk.recv(1024)
# print(str(server_reply,'utf8'))
while True:
input_cmd = input("cmd:").strip() # 用户输入命令
if input_cmd == 'q':break # 用户如果输入的是q,退出输入命令的循环
if not input_cmd:continue # 用户如果直接按了回车,既为空,则进行下次循环
print(input_cmd) # 打印此次用户输入的命令
sk.send(bytes(input_cmd,'utf8')) # 将用户的命令通过socket发送给服务器端 res = bytes('','utf8')
while True:
cmd_exec_data = sk.recv(500) # 接收服务器执行命令后返回的结果
res += cmd_exec_data
if len(cmd_exec_data) < 500:            #当接收到的字节小于500就判断已经接收完了。
break
print(str(res,'utf8'))
sk.close()

这里我们执行命令,得到一些数据量还没有那么大的字符串时没有问题,担当字符串相当大时,就出现之前的那种错误了,原因是我们最初认为的客户端每次都是按最大500字节接收(这个观点错了)。两个因素导致单次接收可能没有500字节。

  因素1,服务端发送会因为网络状态发送数据。如果网络不稳定,传个10几个bytes也是可能的。

  因素2,客户端接收也可能因为网络或者性能,导致这次接收延迟了几百毫秒(内部缓冲机制时间限制也许只有100毫秒)。从而导致本次接收不到500字节。

总结:客户端不是每次接收都是按照最大限额的字节接收的。这样我们的代码:

    while True:
cmd_exec_data = sk.recv(500) # 接收服务器执行命令后返回的结果
res += cmd_exec_data
if len(cmd_exec_data) < 500:        #这里就会在没接收完时,就退出了本次命令执行结果接收呢。
break

最终答案来了,代码如下:

07socket_server.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习,做成可以远程输入命令,客户端获得输出结果,如果你的命令输出结果很多,那么客户端得到的结
'''
import socket
import subprocess
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() # client_data = conn.recv(1024)
# print(str(client_data,'utf8'))
# conn.send(bytes("不要回答,不要回答",'utf8'))
while True:
print("客户端{}已经连接,等待客户端传输命令... ...".format(conn.getpeername()))
client_cmd_re = conn.recv(1024)
if not client_cmd_re:break # 判断当,对方传过来的值为空时,直接退出(在客户端我已经判断用户输入不能为空,所以这里为空,只有一种可能,就是客户端关闭程序了.如果没有这句的break,会导致客户端一旦关闭,服务端也跟着关闭.
# 因为当客户端关闭后,传过来的不知道是什么东西)
print("用户传来了命令:%s"%client_cmd_re) # 打印输出用户传来的命令
cmd_re_str = str(client_cmd_re,'utf8') # 将用户传来的命令转换成str # 将命令执行,并获得执行结果
cmd_exec_result = subprocess.Popen(cmd_re_str,shell=True,stdout=subprocess.PIPE).stdout.read()
if len(cmd_exec_result) == 0 : # 判断结果是不是为空,为空说明用户传过来的命令,本服务器无法执行.
cmd_exec_result = bytes("命令 '{}' 后没有返回执行结果,请检查命令是否正确...".format(cmd_re_str),'utf8') # 提示命令不对 result_size = len(cmd_exec_result) # 计算本次获得到结果是多少字节
conn.send(bytes("CMD_RESULT_SIZE|{}".format(result_size),'utf8')) # 首先将本次将要发送的字符串的大小告诉客户端. conn.send(cmd_exec_result) #紧接着把执行结果发过去
conn.close()

07socket_client.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
当服务端发送过来的字符串字节数过大,一次接收不完,客户端通过判断服务器端是不是发送完,来作为循环接收的依据.
如何判断服务器端是不是发送完成?
根据服务器端发来的大小,判断是否接收完成.
代码如下:
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) # sk.sendall(bytes("请求占领地球",'utf8'))
#
# server_reply = sk.recv(1024)
# print(str(server_reply,'utf8'))
while True:
input_cmd = input("cmd:").strip() # 用户输入命令
if input_cmd == 'q':break # 用户如果输入的是q,退出输入命令的循环
if not input_cmd:continue # 用户如果直接按了回车,既为空,则进行下次循环
print(input_cmd) # 打印此次用户输入的命令
sk.send(bytes(input_cmd,'utf8')) # 将用户的命令通过socket发送给服务器端 server_ack_msg = sk.recv(100)
cmd_res_msg = str(server_ack_msg,'utf8').split('|')
# "CMD_RESULT_SIZE|{}".format(result_size),'utf8')
# print(cmd_res_msg) if cmd_res_msg[0] == "CMD_RESULT_SIZE": # 判断你发来的这个是不是文件大小的标示
cmd_res_size = int(cmd_res_msg[1]) #如果是,把大小付给cmd_res_size变量 res = bytes('','utf8')
recevied_size = 0 # 初始化字符串大小为0
while recevied_size < cmd_res_size: # 如果已接收的字符串大小小于服务器传过来的大小,则循环接收
data = sk.recv(50) # 接收数据
recevied_size += len(data) # 将数据累加
res += data # 累加统计已接收的数据
print(str(res,'utf8')) # 打印最终结果
sk.close()

到此为止,我们认为,socket接收大数据的功能已经实现。大功告成~~~,no,还有错误,当数据量大时,会出现 “socket编程中最大的一个坑 粘包 ”

我们看07socket_server.py中最后发送的代码

            conn.send(bytes("CMD_RESULT_SIZE|{}".format(result_size),'utf8')) # 首先将本次将要发送的字符串的大小告诉客户端.
                            
conn.send(cmd_exec_result)

我们看到一连两次发送。这就会出现“socket编程中最大的一个坑 粘包 ”,原因是缓冲区的问题,你两次发送,缓冲区会把两次要发送的内容放到一起发送。

那么怎么解决呢?

两个方案:

  1.在两次发送之间sleep(1) 间隔1秒,这样缓冲区就失效。但是这种方式low,如果并发大就会很慢。

  2.发送完文件大小后,使用conn.recv(100)这个能阻塞的方法,获取客户端返回来已经接收到文件大小信息的确认信息。(当然客户端也要加返回给服务端的确认信息。)

最终代码如下:

08socket_server.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
socket学习,做成可以远程输入命令,客户端获得输出结果,如果你的命令输出结果很多,那么客户端得到的结
'''
import socket
import subprocess
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting ......') conn,addr = sk.accept() # client_data = conn.recv(1024)
# print(str(client_data,'utf8'))
# conn.send(bytes("不要回答,不要回答",'utf8'))
while True:
print("客户端{}已经连接,等待客户端传输命令... ...".format(conn.getpeername()))
client_cmd_re = conn.recv(1024)
if not client_cmd_re:break # 判断当,对方传过来的值为空时,直接退出(在客户端我已经判断用户输入不能为空,所以这里为空,只有一种可能,就是客户端关闭程序了.如果没有这句的break,会导致客户端一旦关闭,服务端也跟着关闭.
# 因为当客户端关闭后,传过来的不知道是什么东西)
print("用户传来了命令:%s"%client_cmd_re) # 打印输出用户传来的命令
cmd_re_str = str(client_cmd_re,'utf8') # 将用户传来的命令转换成str # 将命令执行,并获得执行结果
cmd_exec_result = subprocess.Popen(cmd_re_str,shell=True,stdout=subprocess.PIPE).stdout.read()
if len(cmd_exec_result) == 0 : # 判断结果是不是为空,为空说明用户传过来的命令,本服务器无法执行.
cmd_exec_result = bytes("命令 '{}' 后没有返回执行结果,请检查命令是否正确...".format(cmd_re_str),'utf8') # 提示命令不对 result_size = len(cmd_exec_result) # 计算本次获得到结果是多少字节
conn.send(bytes("CMD_RESULT_SIZE|{}".format(result_size),'utf8')) # 首先将本次将要发送的字符串的大小告诉客户端.
client_ack = conn.recv(50)
if str(client_ack,'utf8') == "CLIENT_READY_TO_RECV":
conn.send(cmd_exec_result)
conn.close()

08socket_client.py

#!/usr/bin/env python3.5
#__author__:'ted.zhou'
'''
当服务端发送过来的字符串字节数过大,一次接收不完,客户端通过判断服务器端是不是发送完,来作为循环接收的依据.
如何判断服务器端是不是发送完成?
根据服务器端发来的大小,判断是否接收完成.
代码如下:
'''
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) # sk.sendall(bytes("请求占领地球",'utf8'))
#
# server_reply = sk.recv(1024)
# print(str(server_reply,'utf8'))
while True:
input_cmd = input("cmd:").strip() # 用户输入命令
if input_cmd == 'q':break # 用户如果输入的是q,退出输入命令的循环
if not input_cmd:continue # 用户如果直接按了回车,既为空,则进行下次循环
print(input_cmd) # 打印此次用户输入的命令
sk.send(bytes(input_cmd,'utf8')) # 将用户的命令通过socket发送给服务器端 server_ack_msg = sk.recv(100)
cmd_res_msg = str(server_ack_msg,'utf8').split('|')
# "CMD_RESULT_SIZE|{}".format(result_size),'utf8')
# print(cmd_res_msg) if cmd_res_msg[0] == "CMD_RESULT_SIZE": # 判断你发来的这个是不是文件大小的标示
cmd_res_size = int(cmd_res_msg[1]) #如果是,把大小付给cmd_res_size变量
sk.send(b"CLIENT_READY_TO_RECV") res = bytes('','utf8')
recevied_size = 0 # 初始化字符串大小为0
while recevied_size < cmd_res_size: # 如果已接收的字符串大小小于服务器传过来的大小,则循环接收
data = sk.recv(50) # 接收数据
recevied_size += len(data) # 将数据累加
res += data # 累加统计已接收的数据
print(str(res,'utf8')) # 打印最终结果
sk.close()

python2.0 s12 day7的更多相关文章

  1. python2.0 s12 day4

    python2.0 s12 day404 python s12 day4 TengLan回顾上节内容 05 python s12 day4 迭代器原理及使用 本节大纲介绍: 1.迭代器&生成器 ...

  2. python2.0 s12 day3

    s12 day3 视频每节的内容 03 python s12 day3 本节内容概要 第三天的主要内容 上节没讲完的: 6.集合 7.collections 1)计数器 2)有序字典 3)默认字典 4 ...

  3. python2.0 s12 day2

    s12 day2 视频每节的内容 05 python s12 day2 python编码   1.第一句python代码 python 执行代码的过程 文件读到内存 分析内容 编译字节码  转换机器码 ...

  4. python2.0 s12 day8 _ 堡垒机前戏paramiko模块

    堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 paramiko模块是做主机管理的,他模拟了一个ssh. 有两种形式连接形式, ...

  5. python2.0 s12 day8 _ python线程&python进程

    1.进程.与线程区别2.cpu运行原理3.python GIL全局解释器锁4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 6.q ...

  6. python2.0 s12 day8 _ socketserver学习

    Socket 概念 一个socket就是一个点对点的链接.当今,大多数的通信都是基于Internet Protocl,因此大多数的网络Socket都是Internet Protocl(互联网)的通信( ...

  7. Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项(转)

    Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项 参考:https://blog.csdn.net/weixin_40475396/article/detail ...

  8. python3.0与python2.0有哪些不同

    python3的语法跟python2哪里变了. 1. python3中1/2终于等于0.5 了 2. print "Hello World"变成了print("Hello ...

  9. python 2.0 s12 day5 常用模块介绍

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

随机推荐

  1. C++面向对象程序设计的一些知识点(5)

    摘要:运算符能给程序员提供一种书写数学公式的感觉,本质上运算符也是一种函数,因此有类内部运算符和全局运算符之分,通过重载,运算符的“动作”更加有针对性,编写代码更像写英文文章. 1.C++标准允许将运 ...

  2. html+js+css+接口交互+echarts实例一枚

    1. 解决了echarts的展现 2. 解决了echarts全屏幕展现(width:100%;height:100%;) 3. 解决了向接口取数据问题 <!DOCTYPE html> &l ...

  3. js求n行m列二维数组对角线元素之和的思路

    window.onload=function(){   var arr =  [[1,2,4],[5,6,7],[8,9,10]];   var i =3,j=3;   var result1=0,r ...

  4. 登陆时不同浏览器获取session存在的相关疑问?

    问题1:在同一个电脑上,登陆成功后,将登陆信息存放到session域中后,使用另一个浏览器访问时,能否获取这个session域中的值? request.getSession().setAttribut ...

  5. 计时器,主要讲了setInterval()和Date()方法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 拦截iOS系统导航栏返回按钮事件-三种方法

    方法一:在dealloc里面书写监听事件,因为只有pop才会调用dealloc,push不会掉用 - (void)dealloc {YLLog(@"123"); } 方法二:在- ...

  7. 线程池 ManualResetEvent

    线程池: “线程池”是可以用来在后台执行多个任务的线程集合.(有关背景信息,请参见使用线程处理.)这使主线程可以自由地异步执行其他任务. 线程池通常用于服务器应用程序.每个传入请求都将分配给线程池中的 ...

  8. WEB只能输入固定的字符

    <head runat="server"> <title></title> <script type="text/javascr ...

  9. thrift与protobuffer的区别

    thrift由facebook出品,protobuffer由google出品: 下面对比一下这两个的区别.参考:http://zhidao.baidu.com/link?url=yNLBeHhWokf ...

  10. 【json】Jackson的使用

    Jackson所有的操作都是通过ObjectMapper对象实例来操作的,可以重用这个对象实例. 首先定义一个实例: ObjectMapper mapper = new ObjectMapper(); ...