Python socket 套接字实现通信详解
首先:我们介绍一下socket什么是socket:
1.socket在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的接口(接收数据的),此接口接受数据之后交个操作系统
那么为什么?直接给操作系统不是更方便吗?那么你就想错了
因为操作系统的接口远比我们想象的要丑陋复杂,使用操作系统交换数据,非诚繁琐,,开发者们只能想办法让一个中间人和他们打交道,来简单的实现数据交换,那么就是socket套接字.它的作用就是:与操作系统之间数据交换将这些繁琐的操作,进行高度化封装,和简化,
2.我们能够用它实现简单的通信
在Python中有一个简单的内置socket模块我们可以用它实现简单的基于TCP协议的通信
#基于切换连接的循环通信 importsocket#首先我们在文件中导入socket模块 phone=socket.socket()#实例化一个对象 phone.bind(('127.0.01',8765))#bind是存放ip地址的(这里存放的是本地的IP地址) phone.listen(5)#可以设置连接的个数, while1:#循环等待连接 conn,adds=phone.accept() while1:#要循环聊天我们要重复接收发送 try:#异常处理 receives_commands=conn.recv(1024)#接收命令请求,最多接收1024字节当然你也可以调整 receivse_commands=receives_commands.decode('utf-8')#网络传输是以字节的形势的所以我们要进行解码 print(f'来自客户端的消息{receives_commands}')#打印消息 ifreceives_commands.upper(0=='Q':break#正常结束 dispatch_orders=inport('请输入:').strip().encode('utf-8') conn.send(dispatch_orders) exceptConnectionResetError:#客户端异常结束 print('客户端终端') break conn.close()#关闭连接 phone.close#关闭服务端 #客户端 importsocket phone=socket.socket() phone.connect(('127.0.01',8765))#连接服务端地址 while1: dispatch_orders=inport('请输入:').strip().encode('utf-8')#发送请求 ifnotdispatch_orders:print('不能为空')#不能为空 phone.send(dispatch_orders)#发送 ifdispatch_orders.upper()==b'Q':#正常退出 break receives_commands=phone.recv(1024)#接收服务端的回执 receives_commands=receives_commands.decode('utf-8')#解码 print(f'来自客户端的消息{receives_commands}')#打印 phone.close()#关闭客户端
那么我们就通过socket实现了一个简单的通信链接循环
其中我们需要注意的是:
1.阻塞accept和recv当服务器和客户端都属于同种类阻塞时,那么谁都是同步接受或同步发送的状态那么是处于静止的,这样是不合理的(就是bug)
2.当我们设计时我们需要知道发送不能为空,不然服务端是接收不到消息的所以我们设置一个判断
有时我们会发现当我们接受的超过1024字节会发生什么?
那么下面我们就来将回答下这个问题:
下面我们引入一个操作系统的模块
Python中subprocess模块就是用来和cmd命令行进行交流的模块
obj=subprocess.Popen('dir',#实例化对象括号内第一个参数就是我们的cmd命令行的命令,这里我们写的是dir显示文件夹中内容 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj.stdout.read().decode('gbk'))#正确命令 print(obj.stderr.read().decode('gbk'))#错误命令
那么我们在这个基础上建立一个服务端响应客户端命令的机制
importsocket importsubprocess phone=socket.socket() phone.bind(('127.0.01',8695)) phone.listen(5) while1: conn,adds=phone.accept() while1: try: receives_commands=conn.recv(1024) ifreceiver_commands==b'Q':break #obj=subprocess.Popen(Receiving_instructiors, #shell=True, #stdout=subprocess.PIPE, #stderr=subprocess.PIPE ) obj=subprocess.Popen(receives_commands.decode('utf-8')#动态的传入命令 shell=True stdout=subprocess.PIPE stderr=subprocess.PIPE ) #print(obj.stdout.read().decode('gbk'))#正确命令 #print(obj.stderr.read().decode('gbk'))#错误命令 ret=obj.stodut.read()+obj.stderr.read()#将产生的内容进行拼接 conn.send(ret) exceptConnectionResetError: print('客户端终端') break conn.close() phone.close() importsocket phone=socket.socket() phone.connect(('127.0.01',8695)) while1: dispatch_orders=inport('请输入命令:').strip().encode('utf-8') ifnotdispatch_orders:print('输入不能为空') phone.send(dispatch_orders) ifdispatch_orders.upper()==b'Q':break receives_commands=phone.recv(1024) receives_commands=receives_commands.decode('utf-8') print(f'来自客户端的消息{receives_commands}') phone.close()
那么我们就会发现一个问题,当我们输入的help命令的时候超过了1024字节那么怎么办
还发现一个问题那就是当我们输入的下个命令时,还是出来help命令的未传输完成的那部分那么就是这就是粘包了
那么是什么造成的呢?
怎样解决呢?
下次讲解
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。