加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

套接字socker通信,粘包问题的解决

发布时间:2020-12-20 12:45:01 所属栏目:Python 来源:网络整理
导读:一、socker层 (在程序中就是一个模块功能可以直接导入使用) Socker 是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,其实就i是一个门面模式,把复杂的协议放在socker后面。 IP地址: 127.0.0.1是本机回还地址,只能自己识别自己,其他人无法访

一、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(bhello)
client.send(bbaby)

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永远不会粘包

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读