首页 > 其他分享 >网络tcp与udp协议

网络tcp与udp协议

时间:2023-10-21 20:55:08浏览次数:42  
标签:udp 网络 tcp json len str import recv size

TCP协议

TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。

UDP协议

UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头

TCP粘包问题

出现的原因

1、tcp是流式协议,数据像水流一样粘在一起,没有任何边界区分
2、收数据没收干净,有残留,就会跟下次结果混淆在一起

解决粘包问题的核心法门

每次都收干净,不要有任何残留

解决粘包问题的思路

1、拿到数据的总大小
2、recv_size = 0,循环接收,每接收一次,recv_size+=接收长度
3、直到recv_size = total_size,结束循环

TCP客户端与服务端代码(解决粘包问题终极版)

客户端

import json
import struct
from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))

while True:
    cmd = input('请输入命令>>:').strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode('utf-8'))

    # 接收端
    # 1、先收4个字节,从中提取接下来要收的头的长度
    x = client.recv(4)
    header_len = struct.unpack('i', x)[0]

    # 2、接收头,并解析
    json_str_bytes = client.recv(header_len)
    json_str = json_str_bytes.decode('utf-8')
    header_dic = json.loads(json_str)
    print(header_dic)
    total_size = header_dic["total_size"]

    # 3、接收真实的数据
    recv_size = 0
    while recv_size < total_size:
        recv_data = client.recv(1024)
        recv_size += len(recv_data)
        print(recv_data.decode('utf-8'), end='')
    else:
        print()

服务端

# 服务端应该满足两个特点:
# 1、一直对外提供服务
# 2、并发地服务多个客户端
import json
import struct
import subprocess
from socket import *

server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 就是它,在bind前加
server.bind(('127.0.0.1', 8080))
server.listen(5)

#  服务端应该做两件事
# 第一件事:循环地从板连接池中取出链接请求与其建立双向链接,拿到链接对象
while True:
    conn, client_addr = server.accept()

    # 第二件事:拿到链接对象,与其进行通信循环
    while True:
        try:
            cmd = conn.recv(1024)
            if len(cmd) == 0: break
            obj = subprocess.Popen(cmd.decode('utf-8'),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE
                                   )

            stdout_res = obj.stdout.read()
            stderr_res = obj.stderr.read()
            total_size = len(stdout_res) + len(stderr_res)

            # 1、制作头
            header_dic = {
                "filename": "a.txt",
                "total_size": total_size,
                "md5": "123123xi12ix12"
            }

            json_str = json.dumps(header_dic)
            json_str_bytes = json_str.encode('utf-8')

            # 2、先把头的长度发过去
            x = struct.pack('i', len(json_str_bytes))   # i 类型储存的长度绝对够用
            conn.send(x)

            # 3、发头信息
            conn.send(json_str_bytes)

            # 4、再发真实的数据
            conn.send(stdout_res)
            conn.send(stderr_res)

        except Exception:
            break
    conn.close()

标签:udp,网络,tcp,json,len,str,import,recv,size
From: https://www.cnblogs.com/piggthird/p/17779535.html

相关文章

  • 网络基础知识
    1.1数据包和帧数据帧(frame)是数据链路层的协议数据单元,它由帧头,数据部分,帧尾三部分组成,帧头和帧未携带一些信息,比如同步信息,地址信息,差错控制信息等,数据部分包含网络层传递的信息。数据包是TCP/IP协议传输的数据单位,应用于网络层,网络层的数据包传递到数据链路层,加上数据链路......
  • linux 网络管理
    现代人的生活越来越依赖网络,对于一个操作系统来讲,网络功能的支持和管理就更为重要了,本节课我们一起来看一下在CentOS8中如何对网络进行管理NetworkManager和常用工具和基本用法NetworkManager介绍在linux系统中传统的网络管理方法是用过一个叫network的服务来实现,在CentOS7中依......
  • linux网络故障排查
    在日常使用中,经常会出现无法连通的情况,这个时候我们就需要找到问题出在哪里,这里面给各位提供一个生产环境排查网络故障的大体思路,一般情况下如果遇到网络故障,都是通过筛选的方式一点一点的确定问题所在,首先判断是本机的问题还是网络上其它设备的问题,如果同一网络环境中的其它主机......
  • 部署linux网络安装服务器
    一、批量部署概述什么是PXE预启动执行环境(PXE)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持工作站通过网络从远端服务器下载映像,并由此支持通过网络启动操作系统,在启动过程中,终端要求服务器分配IP地址,再用TFTP(trivialfiletransferprotocol)或MTFTP(multicast......
  • umich cv-4-1 卷积网络基本组成部分介绍
    这节课中介绍了卷积网络的基本组成部分(全连接层,激活函数,卷积层,池化层,标准化等),下节课讨论了卷积神经网络的发展历史以及几种经典结构是如何构建的卷积网络组成部分前言卷积层池化层normalization前言在之前提到的全连接神经网络中,我们直接把一个比如说32*32*3的......
  • Sodick 沙迪克 LP20EH3 P12S14 成型机 注塑机 配置网络ip 备忘
    型号:LP20EH3 P12S14Sodick沙迪克LP20EH3 P12S14成型机注塑机配置网络ip备忘 ......
  • 网络规划设计师真题解析--内存编址
    内存按字节编址,利用8K×4bit的存储器芯片构成84000H到8FFFFH的内存,共需()片。A.6      B.8      C.12      D.24答案:C解析:8FFFFH-84000H+1=C000HC000H转换成十进制:C*163+0*162+0*161+0*160=12*163=12*16*16*16=12*4*4*256=48*1024=48KC000H*8bit=48K*8bit(48......
  • 【WSN】基于XBea连续监测无线温度传感器网络附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有
     无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限连到系统上的设备没有发挥作用弹出提示界面如下下: 解决办法,进入cmd--> gpedit.msc,改注册表:  记得重启电脑 ......
  • 使用Spring Integration接收TCP与UDP请求
    1.简介SpringIntegration是一个开源的项目,它是Spring生态系统的一部分,旨在简化企业集成(EnterpriseIntegration)的开发。它提供了一种构建消息驱动的、松散耦合的、可扩展的企业应用集成解决方案的方式。SpringIntegration基于SpringFramework构建,使开发者能够更容易地......