python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)

目录

网络编程

TCP编程

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

UDP编程

多任务原理

启动进程池

进程间通信


网络编程

网络编程概述:

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

 

TCP编程

TCP是建立可靠的链接,并且通信双方都可以以流的形式进行通信发送数据。

客户端:创建TCP链接时,主动发起连接的叫做客户端
服务端:接收客户端连接

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第1张图片

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:在其他地址发现 了请求数据

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第2张图片

 

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

先去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'))

然后在运行时先运行服务器端,再运行客户端

如果先运行客户端将会报错,找不到服务器

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第3张图片

运行结果:first是服务器端

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第4张图片python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第5张图片

 

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 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)

运行结果:

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第6张图片

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)

运行结果:

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第7张图片

父进程和子进程的顺序:父进程结束不能影响子进程

全局变量不能在多个进程中共享

例子:兄弟进程一个改变全局变量,另一个保持不变

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()

运行结果:

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第8张图片

 

启动进程池

使用进程池的方法去调用大量的子进程

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('父进程结束')

运行结果:

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第9张图片

 

进程间通信

用队列去实现两个进程之间的数据传输

子进程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('父进程结束')

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

python(二十七)——网络编程(TCP/UDP编程,客户端与服务器信息传输,多任务原理,进程间通信)_第10张图片

 

 

 

 

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

你可能感兴趣的:(python)