目录
网络编程
TCP编程
客户端与服务器之间信息传输
UDP编程
多任务原理
启动进程池
进程间通信
网络编程概述:
TCP是建立可靠的链接,并且通信双方都可以以流的形式进行通信发送数据。
客户端:创建TCP链接时,主动发起连接的叫做客户端
服务端:接收客户端连接
socket():创建一个socket
bind():绑定端口号
listen():负责监听,可以传一个参数
accept():等待连接
connect():连接
write():建立好连接之后,客户端就可以给服务器写数据了
read():对数据进行思考处理
例子:访问新浪网客户端
# socket库包含了网络编程的所有东西
import socket
#1.创建一个socket
#参数1:指定协议 AF_INET或者AF_INET6
#参数2:SOCK_STREAM执行使用面向流的TCP协议
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#2.建立连接
#参数:是一个元组,第一个元素为要连接的服务器的IP地址,第二个参数为端口
sk.connect(('www.sina.com',80))
sk.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
#等待接收数据
data = []
while True:
#每次接收1K的数据
tempdata = sk.recv(1024)
if tempdata:
data.append(tempdata)
else:
break
dataStr = (b''.join(data)).decode('utf-8')
#断开链接
sk.close()
print(dataStr)
运行结果:访问失败,返回状态码302:在其他地址发现 了请求数据
先去cmd中获取自己的地址IP
然后创建两个py文件,一个是客户端,一个是服务器端
客户端代码:
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('你的IP地址',8081))
count = 0
while True:
count += 1
data = input('请输入给服务器发送的数据')
client.send(data.encode('utf-8'))
info = client.recv(1024)
print('服务器说:',info.decode('utf-8'))
服务器端代码:
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定IP端口
server.bind(('你的地址IP',8081))
#监听
server.listen(5)
#等待链接
clientSocket,clientAddress = server.accept()
print('服务器启动成功......')
# print(str(clientSocket),clientAddress)
while True:
data = clientSocket.recv(1024)
print('收到数据:'+data.decode('utf-8'))
clientSocket.send('你也一样'.encode('utf-8'))
然后在运行时先运行服务器端,再运行客户端
如果先运行客户端将会报错,找不到服务器
运行结果:first是服务器端
相对于TCP,UDP是面向无连接的协议。使用UDP,不需要建立链接,只需要知道对方的IP地址和端口号,就可以直接发送数据包,但不一定能够到达
虽然UDP不可靠,但是相对于TCP,速度快,对于要求不高的数据可以使用UDP传输
udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp.bind(('要发送的IP地址',对方端口号))
udp.send('wahtaijvajvi'.encode('utf-8'))
现代操作系统(Windows、Linux、Mac OS X、Unix等)都支持多任务
多任务:操作系统同时可以运行多个任务
早期电脑主要是单核CPU
单核CPU实现多任务原理:操作系统轮流让各个任务交替执行,QQ执行2us(微秒),切换到微信,再执行2us,再切换到陌陌,再。。。表面上看,每个任务都反复执行下去,但是CPU调度执行速度太快了。导致我们感觉就像所有任务都在同时执行一样。
多核CPU实现多任务原理:真正的并行执行多任务只能在多核CPU上实现,但是由于任务的数量远远多于CPU数量,所以操作系统也会自动把很多任务轮流调度到每个核心上执行
并发:看上去一起执行,任务数大于CPU核心数
并行:真正一起执行,任务数小于CPU核心数
实现多任务的方式:
multiprocessing:跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象
例子:
from multiprocessing import Process
import time
def run():
while True:
print('zk is a gay...')
time.sleep(1.5)
if __name__=='__main__':
print('主进程启动')
#创建子进程
#target说明进程执行的任务
p = Process(target=run)
#启动进程
p.start()
#主进程运行
while True:
print('what happen...')
time.sleep(1)
运行结果:
os.getpid()获取当前进程id号
os.getppid()获取当前进程的父进程id号
例子:
from multiprocessing import Process
import time
import os
def run():
while True:
#os.getpid()获取当前进程id号
#os.getppid()获取当前进程的父进程id号
print('zk is a gay...'+str(os.getpid())+'父id:'+str(os.getppid()))
time.sleep(1.5)
if __name__=='__main__':
print('主进程启动'+str(os.getpid()))
#创建子进程
#target说明进程执行的任务
p = Process(target=run)
#启动进程
p.start()
#主进程运行
while True:
print('what happen...'+str(os.getpid()))
time.sleep(1)
运行结果:
父进程和子进程的顺序:父进程结束不能影响子进程
全局变量不能在多个进程中共享
例子:兄弟进程一个改变全局变量,另一个保持不变
n = 100
def run():
global n
n += 1
#os.getpid()获取当前进程id号
#os.getppid()获取当前进程的父进程id号
print('zk is a gay...'+str(n))
def fun():
global n
print(n)
if __name__=='__main__':
p = Process(target=run)
p.start()
k = Process(target=fun)
k.start()
运行结果:
使用进程池的方法去调用大量的子进程
from multiprocessing import Pool
import time
import os,random
def run(num):
print('子进程%d启动——%s' % (num,os.getpid()))
start = time.time()
#随机暂停时间
time.sleep(random.choice([1,2,3]))
end = time.time()
print('子进程%d结束——%s,耗时:%d' % (num,os.getpid(),end-start))
if __name__=='__main__':
print('父进程启动')
#创建多个进程
#进程池,参数表示可以同时进行的进程数量,默认大小是CPU核心数量
pc = Pool(3)
for i in range(5):
#创建进程放入进程池统一管理
pc.apply_async(run,args=(i,))
#在调用join之前必须先调用close,调用close之后不能再继续添加新的进程了
pc.close()
#进程池对象调用join,会等待进程池中所有子进程结束完毕再去执行父进程
pc.join()
print('父进程结束')
运行结果:
用队列去实现两个进程之间的数据传输
子进程1——》队列——》子进程2
子进程1《——队列《——子进程2
进程间通信,父进程需要创建一个队列,并传递给子进程
例子:
from multiprocessing import Queue,Process
import os,time
def write(q):
print('启动写子进程%s' % os.getpid())
for chr in ['A','B','C','D']:
q.put(chr)
time.sleep(1)
print('结束写子进程%s' % os.getpid())
def read(q):
print('启动读子进程%s' % os.getpid())
while True:
value = q.get(True)
print('value:',value)
print('结束读子进程%s' % os.getpid())
if __name__=='__main__':
#进程间通信,父进程需要创建一个队列,并传递给子进程
q = Queue()
pw = Process(target=write,args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
#pr进程里是一个死循环,无法等待结束,只能强行结束terminate(),如果写进程结束,那么读进程结束
pr.terminate()
print('父进程结束')
运行结果:因为读进程无限循环,所以只能强行结束
一起学习,一起进步 -.- ,如有错误,可以发评论