python高级编程-网络编程、多任务

python高级编程

1 IP地址

用来在网络中标记一台电脑;在本地局域网上是唯一的。

2 端口

一个程序需要收发网络数据,就需要端口号。

3 socket

创建socket

# 创建tcp socket
import socket
s = socket.socket(AddressFamily, Type)

说明:

函数socket.scoket创建一个socket,该函数带有两个参数:

AddressFamily

Typetcp或者udp

发送tcp数据:

import socket
# 创建tcp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 使用套接字

# 关闭套接字
s.close()

udp网络

发送udp数据:

import socket

# 创建upp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

ip_port = (
	"192.168.0.122",
	8080
)

content = input("请输入内容:")

# 发送内容
# udp_socket.sendto("hahahah", 对方的ip和port号)
udp_socket.sendto(content.encode("utf-8"), ip_port)

# 关闭udp套接字
udp_socket.close()

接收udp数据:

import socket

# 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 绑定自己的ip地址,端口号
localaddr = ("", 4040)
udp_socket.bind(localaddr)

# 接收数据
# recv_data是一个元组,其中包含所接收到的信息和发送方的ip地址、端口号
recv_data = udp_socket.recvfrom(1024)  # 1024表示本次接收的最大数据
recv_msg = recv_data[1].decode("gbk") # 收到的信息是windows发来的,就用gbk

# 关闭套接字
udp_socket.close()

一个套接字是可以同时收发数据的。

tcp网络

tcp协议,传输控制协议。

tcpudp的不同点:

  • 1.面向连接(连接已创建才会传输)
  • 2.有序数据传输
  • 3.重发丢失的数据包
  • 4.舍弃重复的数据包
  • 5.无差错的数据传输
  • 6.阻塞、流量控制
tcp客户端

构建流程

import socket


# 创建tcp套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 链接服务器
server_ip = "127.0.0.1"
server_port = 8080
tcp_socket.connect((server_ip, server_port))

# 发送数据/接收数据
send_msg = "cjh"
tcp_socket.send(send_msg.encode("utf-8"))

# 关闭套接字
tcp_socket.close()
tcp服务器

构建流程

import socket


# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定服务器ip、port
tcp_server_socket.bind(("", 4040))

# 让默认的套接字由主动变为被动listen,这样就可以接收别人的连接
tcp_server_socket.listen(128)

# 如果有新的客户端来连接服务器,那么就产生一个新的套接字专门为这个客户端服务
# new_client_socket用来为这个客户端服务
# clientAddr客户端的地址
# tcp_server_socket就可以省下来专门等待其他新的客户端连接
new_client_socket, clientAddr = tcp_server_socket.accept()

# 接收客户端发来的信息
recv_data = new_client_socket.recv(1024)

# 回送数据给客户端
new_client_socket.send("hello".encode("utf-8"))

# 关闭套接字
new_client_socket.close()
tcp_server_socket.close()

77

tcp`注意点
  1. tcp服务器一般情况下都需要绑定ipport

  2. tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动,这是做tcp服务器必须要做的。5阿

  3. tcp_server_socket.setblocking(False) 给套接字设置为非堵塞方式

4多任务-线程

即操作系统可以同时运行多个任务。

线程

创建线程

import threading
import time

def sing():
    for i in range(5):
    	print("--sing--")
		time.sleep(1)

# 创建线程对象
t = threading.Thread(target=sing)
# 执行线程对象(生成的新线程)
t.start()

通过继承Thread类创建线程

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        for i in range(5):
            print("----audiA5----")
            time.sleep()

t = MyThread()
t.start() # 会自动调用run方法

多个子线程会共享全局变量。

target指定将来这个线程去哪里执行代码

args指定将来调用函数的时候传递什么数据过去。args是一个元组。

同步

协同步调,按预定的先后次序进行运行。

互斥锁

当多个线程几乎同时修改某一个共享数据时,需要进行同步控制。

线程同步能够保证多个线程安全访问竞争资源,最简单的机制就是引入互斥锁。

某个线程要更改共享资源时,先将其锁定,此时资源的状态为“锁定”,其他线程就不能更改,直到该线程释放资源后将资源变为“非锁定”,其他线程才能再次锁定该资源。

互斥锁保证了每次只有一个线程进入写入操作,保证了多线程情况下数据的正确性。

# 创建互斥锁
mutex = threading.Lock()

# 上锁
mutex.acquire()

# 解锁
mutex.release()
死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。

避免死锁

  • 添加超时时间。
  • 银行家算法。

5多任务-进程

进程的创建
import multiprocessing

p = multiprocessing.Process(target=test)
p.start()
进程和线程的对比

一个进程中可以有多个线程。

进程之间的通信

Queue队列

import multiprocessing

# 创建队列  其中的3表示最大可存放的数据量,不写的话由系统自行分配
q = multiprocessing.Queue(3)

# 写入数据
q.put(11)

# 取数据
q.get()

# 队列是否为空  False未空   True已空
q.empty()

# 队列是否已满  False未满   True已满
q.full()
进程池Pool

创建进程池

import multiprocessing

# 定义一个进程池,最大进程数为3
po = multiprocessing.Pool(3)

# apply_async(要调用的目标, (传递给目标的参数元组,))
po.apply_async(worker, (1,))

# 关闭进程池
po.close()
# 等待进程池中的所有子进程执行完成
po.join()

6 多任务-协程

迭代器

什么是迭代器

from collections import iterable
from collections import iterator


class Classmate(object):
    def __init__(self):
        self.names = list()
    	self.current_num = 0
        
    def add(self, name):
        self.names.append(name)
        
    def __iter__(self):
        """一个对象如果成为可迭代对象,那么必须有__iter__方法"""
        return self
    
    def __next__(self):
        if self.current_num < len(self.names):
            self.current += 1
            return self.names[self.current_num]
        else:
            raise StopIteration

# 创建实例
classmate = Classmate()
# 调用方法给names中添加元素
classmate.add("ccc")
classmate.add("aaa")
classmate.add("bbb")


# 因为Classmate类中拥有__iter__, __next__方法,因此它是一个迭代器,可以使用for
for name in classmate:
    print(name)

迭代器的应用

可以减少内存空间

class Fibonacci(object):
    """迭代器生成斐波那契数列"""
    def __init__(self):
        self.num = 0
        self.a = 0
        self.b = 1
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.num < 10:
            self.num += 1
            self.a, self.b = self.b, self.a + self.b
            return self.a
        else:
            raise StopIteration

fibo = Fibonacci()

for i in fibo:
    print(i)
生成器

特殊的迭代器。

def generator_demo(num):
    a, b = 0, 1
    current_num = 0
    while True:
        if current_num < num:
            yield a  # 如果函数中有yield语句,那这个就不再是函数,而是生成器模板
            a, b = b, a+b
            current_num += 1
            
# 如果调用的generator_demo中有yield语句,那么此时就是创建一个生成器对象
gen = generator_demo(10)
print(next(gen))
协程-yield

协程

import time

def task_1():
    while True:
        print("1")
        time.sleep(0.1)
        yield

def task_2():
    while True:
        print("2")
        time.sleep(0.1)
        yield

t1 = task_1()
t2 = task_2()
while True:
    next(t1)
    next(t2)
协程-gevent
import gevent

def f1(n):
    for i in range(n):
        print(i)
        gevent.sleep(1)

g1 = gevent.spawn(f1, 5)
g2 = gevent.spawn(f1, 5)
g3 = gevent.spawn(f1, 5)

g1.join()
g2.join()
g3.join()

monkey.patch_all() # 将程序中用到耗时操作的代码全部更改为gevent中自己实现的模块

# 一般使用joinall一次性创建
gevent.joinall([
    gevent.spawn(f1, 5)
    gevent.spawn(f1, 5)
    gevent.spawn(f1, 5)
])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天意不可违.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值