python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)
发布日期:2021-06-30 16:35:25 浏览次数:2 分类:技术文章

本文共 4956 字,大约阅读时间需要 16 分钟。

目录


网络编程

网络编程概述:

  • 自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了
  • 计算机网络就是把各个计算机连接到一起,让网络中的计算机可以互相通信。网络编程就是如何在程序中实现两台计算机的通信
  • 用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信

 

TCP编程

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:        breakdataStr = (b''.join(data)).decode('utf-8')#断开链接sk.close()print(dataStr)

运行结果:访问失败,返回状态码302:在其他地址发现 了请求数据

 

客户端与服务器之间信息传输

先去cmd中获取自己的地址IP

然后创建两个py文件,一个是客户端,一个是服务器端

客户端代码:

import socketclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM)client.connect(('你的IP地址',8081))count = 0while True:    count += 1    data = input('请输入给服务器发送的数据')    client.send(data.encode('utf-8'))    info = client.recv(1024)    print('服务器说:',info.decode('utf-8'))

服务器端代码:

import socketserver = 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是服务器端

 

UDP编程

相对于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核心数

实现多任务的方式:

  1. 多进程模式
  2. 多线程模式
  3. 协程模式
  4. 多进程+多线程模式
multiprocessing:跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象

例子:

from multiprocessing import Processimport timedef 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 Processimport timeimport osdef 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 = 100def 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 Poolimport timeimport os,randomdef 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,Processimport os,timedef 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('父进程结束')

运行结果:因为读进程无限循环,所以只能强行结束

 

 

 

 

一起学习,一起进步 -.- ,如有错误,可以发评论

转载地址:https://kongchengji.blog.csdn.net/article/details/95670584 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python(二十八)——线程通信,生产者与消费者,线程调度,协程
下一篇:python(二十六)——爬虫练习(爬取图片,爬取QQ号)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年05月01日 17时50分51秒