python使用协程,socket进行服务端和客户端之间的通信———进阶版

前言

上一次我们通过简单的测试完成了,从客户端发送信息给服务端,上次文章点这里,最后的效果如下
在这里插入图片描述
但是当我们想要连续发送数据时,这就显然不够用了,于是进阶版就来了。

进程、线程和协程

进程:

系统进行资源分配和调度的基本单位,是操作系统结构的基础,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

比如一台电脑上面的某个软件就是一个进程,而软件里面的一些功能就是线程。

线程:

有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

协程:

协程是比线程更小的一种执行单元,可以认为是轻量级的线程,之所以说轻,其中一方面的原因是协程所持有的栈比线程要小很多,因为协程切换不需要花费时间,所以应用于ngix,大型的秒杀系统等。

总结

一个正常的连接大概分为以下三部分:

  1. 建立数据
  2. 接收数据
  3. 返回数据

所以协程可以解决以下的问题:

(1) 解决线程对的数据的时间:让接收数据的形式,变成非阻塞

(2) 解决线程切换的时间:不同线程,用协程解决线程切换的时间

总结:协程可以解决线程之间的切换问题

服务端

我们在原来的基础上进行修改,主要表现在使用了threading库函数,可以使用pip install threading进行安装。

import socket
import threading

#创建一个tcp socket ip 地址版本为Ip4
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
sock.setblocking(False)  # 设置套接字非阻塞,默认是阻塞模式    找epoll使用,解决网络等待的问题
#绑定IP和端口号
sock.bind(("127.0.0.1",8080))
#最大限度接收数
sock.listen(128)

def handle_func(new_sock):
    while 1:
        try: 
            data = new_sock.recv(4)  # 接收数据

            if len(data) == 0 : #如果接收的数据为空,则关闭通信
                new_sock.close()
                # sock.close()
            else:
                print(data) 
        except:
            pass


while 1:
    try:   
        #取出新的socket  addr是IP,而端口是随机生成的底层做了
        #accept()处理的连接都是三次握手的连接#
        new_cli,addr = sock.accept()
        print('来自一个新的连接', addr,type(addr))
        task = threading.Thread(target=handle_func,args=(new_cli,))
        task.start()
    except:
        pass

客户端

import socket

#创建一个tcp socket ip 地址版本为Ip4
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#设置为IP4
#指定服务器的ip和端口号
sock.connect(("127.0.0.1",8080))

while True:
    data = input("请输入: ")
    if data == 'Q' or data == 'q':
        break
    else:
        sock.send(data.encode())

sock.close()

测试结果

客户端输入:
在这里插入图片描述
服务端输出:
在这里插入图片描述
当客户端重新运行进行通信时,会再次随机分配一个端口号进行连接后通信

在这里插入图片描述

小提示

运行时,依旧是先运行服务端,再运行客户端。
对于服务端代码用的两次try和except,是因为当服务端收到的信息为0时,会报出一个

[WinError 10035] 无法立即完成一个非阻止性套接字操作。

这样的错误,所以用try捕获一下就OK了。

最后,有不明白的地方都可以留言或者私信我!

创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值