其他分享
首页 > 其他分享> > 套接字socker通信,粘包问题的解决

套接字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