socket套接字
2022/4/15 23:16:22
本文主要是介绍socket套接字,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- socket套接字简介
- socket模块
- 通信循环
- 代码优化及链接循环
- 半连接池
- 黏包问题
- 黏包问题的解决
socket套接字简介
# 需求:编写cs架构的程序 实现数据交互 需要编写OSO七层相当复杂,但是由于OSI七层是所有cs架构程序都需要经历的过程,所以由固定的模块 socket模块:提供了快捷方式不需要自己处理每一层 ''' 我们写软件,是看不到socket的,因为都被封装了起来 socket是最低层的原理,很多框架都被封装,不需要深入研究 '''
socket模块
cs架构的软件无论实在编写还是运行,都应该先考虑服务端 # 服务端 import socket server = socket.socket() """ 通过查看源码得知 括号内不写参数默认就是基于网络的遵循TCP协议的套接字 """ server.bind(('127.0.0.1', 8008)) """ 服务端应该具备的特征 固定的地址 127.0.0.1是计算机的本地回环地址 只有当前计算机本身可以访问 """ server.listen(3) '''半连接池:可以决定客户端的等待人数''' sock, addr = server.accept() """ listen和accept对应TCP三次握手服务端的两个状态 """ print(addr) msg = sock.recv(1024) print(msg.decode('utf8')) sock.send('hello client'.encode('utf8')) sock.close() server.close() # 客户端 import socket client = socket.socket() client.connect(('127.0.0.1',8008)) client.send('hello world'.encode('utf8')) msg = client.recv(1024) print(msg.decode('utf8')) client.close() ''' 服务端与客户端的recv与send必须错开,不能同时存在,否则两边,都等待消息或者发送消息,程序阻塞 '''
通信循环
1.解决消息固定的问题 利用input获取用户输入 2.解决通信循环问题 # 服务端 import socket server = socket.socket() server.bind(('127.0.0.1', 8008)) server.listen(3) clint, addr = server.accept() while True: msg = clint.recv(1024) print(msg.decode('utf8')) msg_send = input('请输入信息:') clint.send(msg_send.encode('utf8')) clint.close() server.close() # 客户端 import socket client = socket.socket() client.connect(('127.0.0.1',8008)) while True: msg_send = input('请输入信息:') client.send(msg_send.encode('utf8')) msg = client.recv(1024) print(msg.decode('utf8')) client.close()
代码优化及链接循环
1.发送消息不能为空 统计长度并判断 2.反复重启之后服务端可能会报错:address in use 这个错误在苹果电脑报的比较频繁 windows频率较少 from socket import SOL_SOCKET,SO_REUSEADDR server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 加在bind前 3.链接循环 ''' 如果是windows 客户端异常退出之后服务端会直接报错 处理方式:异常处理 如果是mac或者linux服务端会接收到一个空消息 处理方式:len判断 ''' # 服务端 import socket from socket import SOL_SOCKET,SO_REUSEADDR server = socket.socket() server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) server.bind(('127.0.0.1', 8008)) server.listen(3) clint, addr = server.accept() while True: try: msg = clint.recv(1024) print(msg.decode('utf8')) msg_send = input('请输入信息:') if len(msg_send) == 0: continue clint.send(msg_send.encode('utf8')) except Exception as f: print('客户端断开链接') break clint.close() server.close() # 客户端 import socket client = socket.socket() client.connect(('127.0.0.1',8008)) while True: msg_send = input('请输入信息:') if len(msg_send) == 0: continue client.send(msg_send.encode('utf8')) msg = client.recv(1024) print(msg.decode('utf8')) client.close() 客户端如果异常断开 服务端代码应该重新回到accept等待新的客人 # 当前服务端只能实现一次服务一个人,不能同时服务多个,学习并发之后可以实现
半连接池
listen(5) # 在py文件默认同一时间只能运行一次,如果想单独分开运行多次 就需要用半连接池 # 半连接池 设置的最大等待人数:节省资源 提高效率
黏包问题
data1 = conn.recv(1024) print(data1) data2 = conn.recv(1024) print(data2) data3 = conn.recv(1024) print(data3) client.send(b'hello') client.send(b'jason') client.send(b'kevin') ''' 三次打印店的结果 b'hellojasonkevin' b'' b'' ''' # TCP协议特点 会将数据量比较小并且时间间隔比较短的数据整合到一起发送 并且还会受限制与recv括号内数字的大小(核心问题) 流式协议:跟水流一样不间断 ''' 问题产生的原因其实是因为recv括号内我们不知道将要接受的数据到底多大 如果每次接收的数据我们都能够精确的知道他的大小 那么肯定不会出现黏包 ''' 思路: 核心问题是不知道即将接收的数据多大 如果能够精准的知道数据量多大 那么黏包问题就自动解决了
黏包问题的解决
# struct模块 import struct msg = 'hello world' print(len(msg)) # 11 res = struct.pack('i',len(msg)) #第一个参数是格式 print(len(res)) # 4 res1 = struct.unpack('i',res) print(len(res1)) # (11,) data2 = 'hello baby baby baby baby baby baby baby baby' print(len(data2)) # 45 res2 = struct.pack('i', len(data2)) print(len(res2)) # 4 ret2 = struct.unpack('i', res2) print(ret2) # (45,) ''' pack可以将任意长度的数据打包成固定长度 unpack可以将固定长度的数据解包成打包之前的长度 解决黏包问题思路: 1.将真是数据打包成固定长度的包 2.将福哦顶长度的包先发给对方 3.对方接收到包之后进行解包获取真实数据长度 4.接收真实数据长度 '''
这篇关于socket套接字的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升