套接字socker通信,粘包问题的解决
作者:互联网
一、socker层 (在程序中就是一个模块功能可以直接导入使用)
Socker 是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,其实就i是一个门面模式,把复杂的协议放在socker后面。
IP地址: 127.0.0.1是本机回还地址,只能自己识别自己,其他人无法访问,用于python代码客户端和服务端的测试
二、 套接字(socker)的发展史
1:基于文件类型的套接字家族:AF_UNIX(一切皆文件)
2:基于网络类型的套接字家族:AF_INET(被用于ipv6)
三、tcp协议和udp协议
TCP:可靠的面向连接的协议(如:打电话),传输效率低于全双工通信
UDP:不可靠的、无连接的服务,传输效率高,一对一,一对多
四、套接字(socker)的使用:
TCP协议是基于连接的,必须先启动服务端,然后在启动客户端去连接服务端:
server:服务端
import socket """" 实现服务端24小时不间断的服务功能,固定的IP和port """ server = socket.socket() # 生成一个对象 server.bind(('127.0.0.1',8080)) # 绑定ip和port server.listen(5) # 半连接池 """ 用两层循环 实现客户端与服务端之间的循环交互式 """ while True: conn,addr = server.accept() # 循环接收用户端的请求 print(addr) while True: try:# 解决报错抛出的异常处理(位置,类型,) data = conn.recv(1024) print(data) if len(data) == 0 : break # 针对mac和 Linux 客户端异常退出之后 conn.send(data.upper()) # 返转成大写 except ConnectionRefusedError as e: # 提示的报错信息 print(e) break conn.close()
client:客户端
import socket client = socket.socket() client.connect(('127.0.0.1',8080)) while True: msg = input("请输入:").encode("utf-8") if len (msg) == 0: continue client.send(msg) data = client.recv(1024) print(data)
send(发出)与recv(接收)对应关系,不能出现两边都相同的情况
recv 是跟内存要数据的,
TCP的特点:
会将数据量比较小的并且时间间隔比较短的数据
一次性打包发送给对方
利用socker模块,用代码实现了服务端与客户端的实际交互情况,IP地址和pore端口地址必须完全匹配,其中注意一些概念 如 server.listen(5) # 半连接池 指的是规定客户端访问的量,报错的异常处理
一个作为接收端,一个作为反馈请求端,所用的参数也不一样
五、黏包
黏包:指的是当客户端同时请求所传输的内容过大,过长是,服务端反馈的结果可能只有其中的一部分,显示不全,在执行其他命令的时候又接受收到了之前执行的另外一部分的结果。
补充的subprocess子进程模块
import subprocess cmd = input('cmd>>>:') obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) print(obj.stdout.read().decode('gbk')) # 正确命令返回的结果 print(obj.stderr.read().decode('gbk')) # 错误的命令返回的结果 # subprocess获取到的数据 拿完就没有了 不能重复的拿 # print(obj.stdout.read().decode('gbk')) # 正确命令返回的结果 # print(obj.stderr.read().decode('gbk')) # 错误的命令返回的结果
只能单次获取请求的数据,取完就没了, 不能重复的取
该模块可以在python解释器里,实现终端的请求命令行执行并打印结果:
它的功能以及常用的操作
# subprocess模块 # 1.用户通过网络连接上了你的这台电脑 # 2.用户输入相应的命令 基于网络发送给了你这台电脑上某个程序 # 3.获取用户命令 里面subprocess执行该用户命令 # 4.将执行结果再基于网络发送给用户 # 这样就实现 用户远程操作你这台电脑的操作 # ''
当有黏包现象存在时如何解决?(即数据过大过长时)
服务端client:
1:先制作一个发送给客户端色字典
2:制作字典的报头
3:发送字典的报头
4:再发真实的数据
客户端srever:
1.先接受字典的报头
2.解析拿到字典的数据长度
3.接受字典
4.从字典中获取真实数据的长度
5.接受真实数据
用字典打包好报头,获取固定的长度后在传输
简单黏包问题的存在,接收的数据和传出去的不一样
client 客户端
import socket client = socket.socket() # 拿电话 client.connect(('127.0.0.1',8080)) # 拨号 写的是对方的ip和port client.send(b'hello') client.send(b'baby')
server:服务端
import socket server = socket.socket() # 买手机 不传参数默认用的就是TCP协议 server.bind(('127.0.0.1',8080)) # bind((host,port)) 插电话卡 绑定ip和端口 server.listen(5) # 开机 半连接池 conn, addr = server.accept() # 接听电话 等着别人给你打电话 阻塞 data = conn.recv(5) # 听别人说话 接收1024个字节数据 阻塞 print(data) data = conn.recv(5) # 听别人说话 接收1024个字节数据 阻塞 print(data)
注意:只有TCP有粘包现象,UDP永远不会粘包
标签:socker,socket,server,client,print,接字,粘包,服务端,客户端 来源: https://www.cnblogs.com/Gaimo/p/11317311.html