TCP是一种流式协议

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。

流式协议的特点是什么?就像流水连续不断那样,消息之间没有边界。例如send了3条消息(这里的“消息”是指应用层的一个完整的协议包),分别是100字节、50字节、80字节,recv时可能收到的是230字节,就是说一次recv收到了3条消息,需要应用逻辑自己对recv到的数据进行分析,得出完整的消息。能一次recv到多个消息,也可能一次recv到一个半消息或半个消息,都是有可能的,这就是流式协议的特点。有的文章讲的粘包也是这个概念。

消息分包

既然TCP是一种流式协议,需要应用层自己来分析出完整的消息,那有哪些方式来确定一个完整消息呢?这个就是应用层通讯协议设计的工作了。

先看看最常见的HTTP协议是如何来分包的。HTTP协议是一种文本协议(非二进制协议),用\r\n\r\n来分割消息头和消息体,HTTP请求的消息头中有Content-Length来告知消息体有多大,如果没有该字段就表示无消息体,GET请求大多是这样。HTTP响应的消息头中,或者有Content-Length,或者有Transfer-Encoding: chunked告知以chunk模式分析消息体。

HTTP请求信息由3部分组成:

1、请求方法(GET/POST)、URI、协议/版本

2、请求头(Request Header)

3、请求正文,请求正文和请求头要有空行。这个空行必须存在,说明结束请求头传输,开始传输正文请求。

HTTP请求

GET/HTTP/1.1
[请求头]
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.;Window NT5.)
Accept-Encoding:gzip,deflate
[请求正文]
username=ring&password=

http响应格式

HTTP应答与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

1、状态行

2、响应头(Response Header)

3、响应正文

HTTP响应1:Conetent-Length

HTTP/1.1 200 OK
SERVER: name
DATE: Fri, 22 Dec 2017 10:50:38 GMT
Content-Type: image/gif 
Content-Length: 43
Last-Modified: Mon, 1 Dec 2017 13:23:42 GMT
Connection: keep-alive
Expires: Fri, 22 Dec 2017 10:50:38 GMT
Cache-Control: max-age=0
Accept-Ranges: bytes GIF89a二进制数据 HTTP响应2:Transfer-Encoding
HTTP/1.1 200 OK
DATE: Fri, 22 Dec 2017 10:55:50 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Fri, 22 Dec 2017 10:55:50 GMT
Cache-Control: max-age=7200
Content-Encoding: gzip 91a
具体的数据
0

HTTP用\r\n\r\n来分割消息头和消息体,这种用特定字符/字符串来分割或分包的方式,还有不少协议用到。例如FTP/SMTP/POP3都是用\n来作为一个命令结束的标志。这种消息分包的方式,需要应用层去扫描已recv到的数据,性能上还不够高效,代码不严谨的还容易被攻击。在需要自定义协议的项目中,不少选择用二进制协议,解析高效,安全性更好些。

最简单的二进制协议分包方式是消息的头4个字节表示消息的总长度。这种方式还需要对最大消息长度做个限制,例如64K或1024K大小,避免超大数据包对接收方缓冲区的破坏。更进一步的,可以加入简单校验方法。例如消息头1个字节固定式0x2,消息的最后1个字节固定式0x3,消息总长度放在第2~5字节。这样收到完整消息后,如果头尾不是0x2和0x3,就直接异常处理。

协议设计

消息分包是协议设计的一个工作,协议设计的话题还不少,这里以HTTP协议为例,简要的说说里面设计的点,自己设计的协议也可以对照着有选择的使用,原理是共通的。

由消息头+消息体组成:空行分割HTTP head和body,HTTP头的每一行以\r\n结尾,空行就是\r\n\r\n
消息分包:如上所述,HTTP用Content-Length和Transfer-Encodeing来分包
消息压缩:请求中有Accept-Encoding字段,响应中用Content-Encoding字段表明压缩方式,一般采用gzip压缩
消息加密:https  (SSL: Secure Socket Layer)
消息ID:URL就是消息ID
响应的状态码:第一个数字定义了响应的类别。
    1xx:指示信息--表示请求已接收,继续处理
    2xx:成功--表示请求已被成功接收、理解、接受
    3xx:重定向--要完成请求必须进行更进一步的操作
    4xx:客户端错误--请求有语法错误或请求无法实现
    5xx:服务器端错误--服务器未能实现合法的请求
协议版本号: HTTP/1.1中的1.1就是HTTP 1.1版本
长连接:请求中Connection: keep-alive表示希望服务器保持连接,减少TCP连接的开销
字符集: Content-Type字段表明了字符集,例如: Content-Type: text/html; charset=gb2312
字符转义:URL中的参数需要做URL转义处理,例如http://xx.com/do?name=t%2F%3F%23%3Daa表示name为t/?#=aa

在我们自己设计协议时,可以有选择的使用,如果消息比较大,可以采用支持压缩;如果要兼容多个版本的协议,那版本号必不可少。如果采用二进制协议,字符集和字符穿衣的用处不大。

TCP、消息分包和协议设计的更多相关文章

  1. 主程的晋升攻略(4):TCP、消息分包和协议设计

    在<主程的晋升攻略(3):IP.DNS和CDN>中,一次网络请求经过DNS解析知道了目的IP,如今就要发出网络包,这里我们说一说TCP的相关话题. TCP是一种流式协议 讲网络编程的教科书 ...

  2. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  3. TCP协议设计原理

    TCP协议设计原理 最近去了解TCP协议,发现这是一个特别值得深思的协议.在本篇博客中,不会长篇大论的给大家介绍TCP协议特点.包头格式以及TCP的连接和断开等基本原理,而是会带大家深入理解为什么要这 ...

  4. Mina、Netty、Twisted一起学(二):TCP消息边界问题及按行分割消息

    在TCP连接开始到结束连接,之间可能会多次传输数据,也就是服务器和客户端之间可能会在连接过程中互相传输多条消息.理想状况是一方每发送一条消息,另一方就立即接收到一条,也就是一次write对应一次rea ...

  5. 分布式发布订阅消息系统 Kafka 架构设计[转]

    分布式发布订阅消息系统 Kafka 架构设计 转自:http://www.oschina.net/translate/kafka-design 我们为什么要搭建该系统 Kafka是一个消息系统,原本开 ...

  6. 2018-2019-1-20165221&20165225 《信息安全系统设计》实验五:通讯协议设计

    2018-2019-1-20165221&20165225 <信息安全系统设计>-实验五:通讯协议设计 OpenSSL学习: 简介: OpenSSL是为网络通信提供安全及数据完整性 ...

  7. python 全栈开发,Day33(tcp协议和udp协议,互联网协议与osi模型,socket概念,套接字(socket)初使用)

    先来回顾一下昨天的内容 网络编程开发架构 B/S C/S架构网卡 mac地址网段 ip地址 : 表示了一台电脑在网络中的位置 子网掩码 : ip和子网掩码按位与得到网段 网关ip : 内置在路由器中的 ...

  8. im协议设计选型【转】

    一.im协议的分层设计所谓“协议”是双方共同遵守的规则,例如:离婚协议,停战协议.协议有语法.语义.时序三要素.(1)语法:即数据与控制信息的结构或格式(2)语义:即需要发出何种控制信息,完成何种动作 ...

  9. 网络编程基础socket 重要中:TCP/UDP/七层协议

    计算机网络的发展及基础网络概念 问题:网络到底是什么?计算机之间是如何通信的? 早期 : 联机 以太网 : 局域网与交换机 广播 主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无 ...

随机推荐

  1. 如何在Ubuntu上开启SSH服务

    更新源列表 打开"终端窗口",输入"sudo apt-get update"-->回车-->"输入当前登录用户的管理员密码"-- ...

  2. CodeForces - 375A Divisible by Seven(数学)

    https://vjudge.net/problem/48715/origin 题意:给出必定含1689四个数字的字符串,随意交换位置构造出能被7整除的数. 分析:数学思维题.观察发现1689的排列与 ...

  3. PhotoshopCC2018安装流程以及破解

    2018版增加了不少功能,也对优化PS软件进行了不少的优化,界面更加简洁美观 这里以64位为主. 1.首先下载好PhotoshopCC安装包和破解包,分别解压 2.解压完毕后,在安装包里面双击Setu ...

  4. int、bool和str

    int bit_length 返回以二进制表示的最短长度 print(int.bit_length(10)) 结果 4 Process finished with exit code 0 int() ...

  5. 细说shiro之五:在spring框架中集成shiro

    官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <gr ...

  6. vue2.0页面缓存和不缓存的方法

    // 模板中: <div class="home"> <keep-alive> <router-view v-if="$route.meta ...

  7. 双系统中卸载Ubuntu后又efi系统分区删除方法

    参考:https://blog.csdn.net/qq_28057541/article/details/51723914 首先 window键(窗口键) + R ,然后输入 Diskpart 打开命 ...

  8. SQL 查看表字段及说明

    select A.comments,A.column_name,B.DATA_TYPE||'('||B.DATA_LENGTH||')' from user_col_comments A inner ...

  9. 15款Java程序员必备的开发工具(转)

    如果你是一名Web开发人员,那么用膝盖想也知道你的职业生涯大部分将使用Java而度过.这是一款商业级的编程语言,我们没有办法不接触它 对于Java,有两种截然不同的观点: 一种认为Java是最简单功能 ...

  10. angular vue react web前端三大主流框架的对比

    首先,我们先了解什么是MVX框架模式? MVX框架模式:MVC+MVP+MVVM 1.MVC:Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职责分 ...