137 python|第八部分:并发网络编程网络编程下

Posted 缓缓而行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了137 python|第八部分:并发网络编程网络编程下相关的知识,希望对你有一定的参考价值。

socket *socket * conn.send( msg = input( tcp_socket.send(msg.encode()) msg == data = tcp_socket.recv( conn,addr = tcp_socket.accept() print( data = conn.recv( print( conn.send( conn.close() conn,addr = tcp_socket.accept() data = conn.recv( conn.send( conn.close()True: msg = input( tcp_socket = tcp_socket.connect(ADDR) tcp_socket.send(msg.encode()) msg: data = tcp_socket.recv( tcp_socket.close()

socket * q = conn.recv( key,value data.items(): key q: conn.send(value.encode()) conn.send( sock = socket(AF_INET,SOCK_STREAM) sock.bind(( sock.listen( conn,addr = sock.accept() xy(conn) conn.close() sock.close()__name__ == main()

socket * sock = socket() sock.connect(ADDR) sock.send(msg.encode()) data = sock.recv( sock.close() data.decode() msg = input( msg: data = xy(msg) print(__name__ == main()

运行看看:

data = conn.recv( data data == conn.send(socket * fw = open( data = conn.recv( data: fw.write(data) fw.close() sock = socket(AF_INET,SOCK_STREAM) sock.bind(( sock.listen( conn,addr = sock.accept() print( recv_image(conn) conn.close() sock.close()__name__ == main()


  • socket *   fr = open(                    data = fr.read(       data:                  sock.send(data)   fr.close()   sock = socket()   sock.connect(ADDR)   send_image(sock)   sock.close()__name__ ==    main()
    先运行服务器,再运行客户端

    图片完成了从客户端(下载)发送到了服务器(day11)




    socket * data = conn.recv( print(data.decode())socket * sock.send(item.encode())sock.send(b"##"# 发送完data,向服务器发送##
    sock.close()
    运行后发现,##并没有作为循环结束的条件出现,和前面发送的数据粘在了一起,所以服务器收不到退出条件,会一直循环下去,直到ctrl c 人为退出。


    那么怎么解决粘包问题呢?

    首先我们可以通过设置sleep控制发送速度


    运行一下,发现程序虽然可以自动结束了,但数据之间仍然有粘连


    然后,我们试着在for循环里增加消息边界:
    注:\\n也可以替换成其他的字符

    运行后发现粘包问题被解决了


    3.5 TCP与UDP对比


    01.传输特征

    * TCP提供可靠的数据传输,但是UDP则不保证传输的可靠性
    * TCP传输数据处理字节流,而UDP处理为数据包形式
    * TCP传输需要建立连接才能进行数据传,效率相对较低;UDP比较自由,无需连接,效率较高

    02.套接字编程区别

    * 创建的套接字类型不同
    * tcp套接字会有粘包,udp套接字有消息边界不会粘包
    * tcp套接字依赖listen accept建立连接才能收发消息,udp套接字则不需要
    * tcp套接字使用send,recv收发消息,udp套接字使用sendto,recvfrom

    03.使用场景

    1.tcp更适合对准确性要求高,传输数据较大的场景
    * 文件传输:如下载电影,访问网页,上传照片
    * 邮件收发
    * 点对点数据传输:如点对点聊天,登录请求,远程访问,发红包

    2.udp更适合对可靠性要求没有那么高,传输方式比较自由的场景
    * 视频流的传输:如部分直播,视频聊天等(udp允许丢帧,tcp则具有可靠性,如果在网速不好的情况下采用tcp传输,可能会卡成ppt,当然也可能使用tcp结合一些延迟技术)
    * 广播:如网络广播,群发消息
    * 实时传输:如游戏画面

    在一个大型的项目中,可能既涉及到TCP网络又有UDP网络。

    下篇文章预告:多任务编程&网络并发模型




    参考资料


    [1] 怎样区别交换机、路由器和猫

    https://jingyan.baidu.com/article/046a7b3e15eb73f9c37fa96f.html

    [2] 计算机网络中的基本器件(网卡,集线器,交换机,路由器)

    https://www.cnblogs.com/mlgjb/p/8092991.html

    [3] 图解 | 原来这就是网络

    https://www.cnblogs.com/flashsun/p/14266148.html

    [4] 图解 | 原来这就是TCP

    https://www.cnblogs.com/flashsun/p/14322660.html

    [5] 【TCP协议】(1)---TCP协议详解

    https://www.cnblogs.com/qdhxhz/p/10267932.html

    [6] TCP的三次握手和四次挥手 

    https://www.cnblogs.com/zhonglongbo/p/12701607.html

    [7] 详解TCP连接的“三次握手”与“四次挥手”(上)

    https://www.cnblogs.com/AhuntSun-blog/p/12028636.html

    [8] 详解TCP连接的“三次握手”与“四次挥手”(下)

    https://www.cnblogs.com/AhuntSun-blog/p/12037852.html



    公众号推荐


    公众号:低并发编程  博客园:闪客sun




    花样早餐展

    139 python|第八部分:并发网络编程多任务编程下--线程

    threading Threadtime sleep i range( sleep( print(i range( sleep(threading Threadtime sleep print( sleep(sec) print(i range( t = Thread(target = func, args = ( kwargs = ) t.start()threading Threadtime sleep self.song = song super().__init__() i range( sleep( print(threading Threadfrom time sleepthreadingtime print(% threading.currentThread().getName()) event.wait() print(% threading.currentThread().getName())threading Thread,Lock lock.acquire() a != b: print( lock.release() lock.acquire() a += b += lock.release()time sleep self.id = id self.balance = balance self.balance -= amount self.balance += amount self.balance from_.lock.acquire() from_.get(amount) sleep( to.lock.acquire() to.put(amount) from_.lock.release() to.lock.release() #一方给另一方转钱trans(Peiqi,George,10)
    print(\'Peiqi:\',George.getbalance())print(\'George:\',Peiqi.getbalance())
    运行结果:
    在这段代码中,场景是一方给另一方转钱,程序运行没有问题。


    但是如果两方同时向对方转钱,会出现阻塞。

    阻塞的原因是产生了死锁。根据上面提到的死锁的避免方式,我们只要让死锁四个产生条件不要同时出现即可。


    这题可以通过破坏“请求和保持条件”入手。可以让出钱一方上锁-取钱后直接进行解锁来实现需求。

    运行结果:




    05 GIL(global interpreter lock)问题 


            

    5.1 概念

      
    ▍GIL(全局解释器锁)概念
    为了利用多核,Python利用支持多线程,为了解决多线程之间数据完整性和状态同步的问题,python通过加锁的方式来处理(通过GIL给解释器加锁,让解释器同一时刻只能解释一个线程)。

    但这也大大降低了线程的执行效率,因为遇到阻塞时线程会主动让出解释器,去解释其他线程。所以python在执行多阻塞任务时可以提升程序效率,其他情况并不能对效率有所提升。

    为了提高效率,我们可以尽量使用进程完成无阻塞的并发行为,还可以不使用c作为解释器,改用java或者c#解释器

    关于python的解释器,可以看下面这篇文章了解
    https://blog.csdn.net/orangleliu/article/details/39204897

    ▍结论

    1.GIL问题与python语言本身没什么关系,属于解释器设置历史的问题。

    2.在无阻塞状态下,多线程程序执行效率并不高,甚至还不如单线程。

    3.python多线程只适用于执行有阻塞延迟的任务情形。



    06 进程和线程的联系&区别 



    6.1 联系&区别


    进程和线程的联系&区别
    类别说明
    联系1.两者都是多任务编程,都能使用计算机多核资源
    2.一个进程可以有多个分支线程,两者有包含关系
    3.多个线程共享进程资源,在共享资源操作时往往需要同步互斥处理。
    区别1.进程的创建和删除消耗的计算机资源比线程多
    2.进程空间独立,数据互不干扰,有专门的通信方法;线程使用全局变量通信
    3.python线程存在GIL问题,但进程没有
    mysql也是一个由多进程构成的例子,mysql的InnoDB引擎是单进程里包含多线程的例子。



    ▍下期预告:网络并发模型





    参考资料


    [1] Python线程指南 
    https://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html
    [2] python多线程详解
    https://www.cnblogs.com/luyuze95/p/11289143.html
    [3] _thread --- 底层多线程 API
    https://docs.python.org/zh-cn/3/library/_thread.html
    [4] threading --- 基于线程的并行
    https://docs.python.org/zh-cn/3/library/threading.html


    拓展资料


    [1] python术语对照表
    https://docs.python.org/zh-cn/3/glossary.html
    [2] org域名
    https://baike.so.com/doc/5468111-5706023.html
    [3] 通用顶级域
    https://baike.so.com/doc/748060-791805.html
    [4] [Python]解释器的几种实现版本
    https://blog.csdn.net/orangleliu/article/details/39204897


    花样早餐展

    以上是关于137 python|第八部分:并发网络编程网络编程下的主要内容,如果未能解决你的问题,请参考以下文章

    139 python|第八部分:并发网络编程多任务编程下--线程

    138 python|第八部分:并发网络编程多任务编程上--进程

    第八章 网络的时代—网络开发

    Python之旅.第八章.网络编程

    Python开发第八篇:网络编程

    Python之路第八篇--Python基础之网络编程