即时通信 选择UDP还是TCP协议
之前做过局域网的聊天软件,现在要做运行在广域网的聊天软件。开始接触网络编程,首先是接触到TCP和UDP协议
在网上查资料,都是这样描述 TCP面向连接,可靠,数据流 。UDP无连接,不可靠,数据报。但是实际使用的时候就会有很多疑惑了,比如我们做一个聊天软件 客户登陆我们的服务器,我们到底是使用哪一种协议呢 是使用TCP和客户端保持常连接,还是使用UDP这种无连接,数据传输不可靠 还是使用TCP在和客户端交换一次数据后就断开连接 需要的时候再连接。
这是3种情况。这几种情况针对于需要服务器转发的消息,需要客户端之间点对点传输的情况除外
1。使用TCP协议和客户端保持常连接(长连接) 从客户登陆到客户离线,在客户端与服务端之间一直保持着一个TCP连接,两者之间可以随时相互通信,信息的传输是可靠的,这是我们最想看到的方式。但是我们不禁要问了 一台服务器能保持多少个TCP连接呢,这是我一直困惑的,前端时间遇到一个有些经验的程序员 按我的理解,使用这种常连接方式的C/S软件,如果服务器是一台普通的计算机 一般情况下,500多个TCP连接之后就会开始出现问题。对于真正的服务器,我们可以想象它是通过一个网络设备充当网关(类似于路由器,硬件防火墙)连接到公网,服务器连接到网关,服务器对外服务的端口都和网关有映射关系。所以我们客户端知道服务器公网IP和服务端口 可以直接发起TCP连接请求。所有的数据交换都会经过服务器的网关 而这个网关,根据我的了解 它能并发处理500到10W个连接不等,这主要取决于这个硬件防火墙的质量,直接和价格相关。我们一般家里或者寝室使用的路由器都能同时处理几百个连接,使数据几乎是没多少延迟就通过网关了,而服务器的网关我们可以想象 再差也能支持几千个并发连接吧,而在服务器网关背后有可能不止一台服务器,对于大规模的即时通讯软件来说 服务器网关背后肯定是服务器集群,服务端也是分布式的 服务端运行在这个服务器集群的多台服务器中,由多台服务器来对客户端发来的数据进行协同地均衡负载处理,以支持海量用户 处理完成之后通过网关把结果发给客户。我们可以想象,像腾讯QQ之类的大规模即时通讯软件,经常性的是几千万用户同时在线 如果都采用常连接的方式。岂不是要服务器的硬件防火墙监控数千万个连接了,就算分布式服务端能承受这么多用户 网关也受不了,而且有理由相信服务器也受不了 。所以对于大规模即时通讯,尤其是用户数量众多 肯定不能用TCP常连接的方式,这种方式只适合于小规模的即时通讯,如局域网,公司内部的即时通讯等 对于大规模的,用户数量众多的C/S软件 应当采用UDP协议进行数据传输,网关就不停收发数据包就可以了
2。使用TCP协议和客户端进行短命连接,用了就关 比如客户登陆请求好友列表,我们就和他建立TCP连接发给他好友列表,然后关掉连接 当用户要给另外一个客户发信心我们再建立连接,数据传完我们又关掉连接 这种方式,无疑服务器可以承载更多的用户登陆。但是缺点也是非常明显的 一般情况下我们接收的数据都不大,每次发一点点消息都要建立连接 TCP本来就比较消耗网络资源,这样毫无规律的断断连连 连连断断,加上本来这种方式就有较高的延迟 也不适合大规模的即时通讯
3。使用UDP协议与客户端无连接 UDP无连接,不可靠,数据报。无连接,代表了它快速,资源消耗小 接着我们要看“不可靠”,这个不可靠它究竟不可靠到了什么程度呢?事实上,在Internet上传输的UDP包从A发送给B 它完整地到达几率一般情况下还是相当之高的。我们开发一个多用户的即时通讯软件 采用UDP传输消息的时候,报文被划分成包 一个UDP包究竟是多大?经过我的了解一个UDP用户包最大大小是64KB 根据网络状况,实际在传输包的时候可能把包划成若干个分片 一个分片的最大大小是1640B 可以保存好几百个汉字。我们在使用QQ的时候应该也注意到了,我们给好友发送信息的时候都有字数上限的,我的理解这是为了让传输的信息不至于太长而分成多个包,保证所有信息装在一个包里,要么完整发送,要么传输失败。我们客户端向服务端发送的消息 一般来说可以定义一个结构体 这个结构体包含指令 消息正文等要素(见之前写的进程间通信基础知识)我们都知道这个结构体其实很简单,只有几个成员 包括正文,对于一般的文字消息,或者请求 更新好友列表的消息对象被序列化后也很小,一个UDP包被完全可以装下这个序列化后的对象。到这里我们再来看看UDP协议的“不可靠”,“数据报”。UDP协议提供数据报机制传输信息 如果报文比较长,比如一个文件,一个图片 要被划分成若干个数据包,由于对于一般的文字消息和其它指令都是比较小的 它们会被放在一个包里面,由于UDP是无连接的 不可靠的,如果发生丢包,不会重传 所以不能保证数据包能完整并准确地到达目的地,但是对于我们的即时通讯软件来说 一般的聊天信息比较小,比如我们给一个好友发送一条聊天信息“今天我很高兴”,会不会服务器转发的时候只收到“今天我很高”,再传给好友的时候变成了“今天”,答案是不会发生这种情况的 UDP虽然描述是不可靠,不过依然在数据包中包含了头信息描述了包的大小等信息,在包进行转发的过程中 如果数据不完整,是会被网络设备发现的,比如中途一个转发这个包的路由器发现了一个不完整的UDP包会直接丢弃,如果是TCP 当有包被丢弃了会进行重传,对于UDP 包在传输过程中由于数据的缺失被丢弃不会进行重传 我们顶多就是一条信息发送失败了,而这种概率一般情况下是非常低的 。
经过以上的一些思考,我得出了这样的结论 大规模即时通讯应当采用UDP协议进行常规的通信,TCP可以作为一种辅助手段
经过一些学习,思考和实践 我得出了心目中的大规模即时通讯软件的总体架构:
1。以UDP协议作为主要数据传输协议
2。服务端使用一个数据库保存信息(分布式数据库)
3。服务端是是分布式的,通过异步多线程技术,集群服务等 通过服务器集群共同运行服务端,对外进行海量信息处理(转发,暂存,广播消息)
4。客户端也属于分布式应用程序,具有一些服务端的功能 在进行语言,视频,文件传输的时候,可由服务端协调 在两个客户端直接进行点对点通信
这样的总体架构能够保证大规模即时通讯,更需要做的地方就是对数据的查询优化 服务端的性能优化等。
即时通信 选择UDP还是TCP协议的更多相关文章
- Python基础教程之udp和tcp协议介绍
Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...
- Java第三阶段学习(八:网络通信协议、UDP与TCP协议)
一.网络通信协议 1.概念: 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传 ...
- 通信协议之HTTP,UDP,TCP协议
1.UDP,TCP,HTTP之间的关系 tcp/ip是个协议组,它可以分为4个层次,即网路接口层,网络层,传输层,以及应用层, 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协 ...
- day28——C/S与B/S架构、网络通信原理、osi七层协议、UDP、TCP协议、TCP的三次握手与四次挥手
day28 C/S B/S架构 C:client 客户端 B:browse浏览器 S:server 服务端 C/S C/S架构:基于客户端与服务端之间的通信 QQ.游戏.皮皮虾 优点:个性化设 ...
- python网络编程——使用UDP、TCP协议收发信息
UDP UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送. UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内. UDP ...
- 使用UDP和TCP协议的各种应用和应用层协议
IGMP和ICMP是传输层协议
- 移动端IM系统的协议选型:UDP还是TCP?
1.前言 对于有过网络编程经验的开发者来说,使用何种数据传输层协议来实现数据的通信,是个非常基础的问题,它涉及到你的第一行代码该如何编写. 从PC时代的IM开始,IM开发者就在为数据传输协议的选型争论 ...
- 协议森林08 不放弃 (TCP协议与流通信)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...
- TCP协议与流通信
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...
随机推荐
- 行高(line-height)
line-height属性 设置元素中文本行高.
- 记一次ssh配置的锅
我们在使用git来管理代码的时候不可避免的要用到ssh密匙,这个密匙怎么配置的百度上很多. 我这边是使用sourcetree来配合管理代码的,但是我ssh配置好了以后无论是克隆代码还是推送代码都提示我 ...
- C++学习(三十七)(C语言部分)之 链式栈(推箱子实现)
用链表实现栈一开始在表头插入,就要一直在表头插入一开始在表尾插入,就要一直在表头插尾表头当栈底 也可以把表尾当栈底 实现的测试代码笔记如下: #include<stdio.h> #incl ...
- lucas 模板 洛古模板题
#include<bits/stdc++.h> #define int long long using namespace std; ; int a[maxn]; int quick(in ...
- Appium介绍及工作原理
一.Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持IOS.Android及FirefoxOS平台.Appium使用WebDriver的 ...
- UltraISO 9.7.1.3519注册码
王涛 7C81-1689-4046-626F redcaps 82C6-3DEF-AB07-0EC0
- 20165308实验三 敏捷开发与XP实践实验报告
实验三 敏捷开发与XP实践实验报告 实验目的 安装 alibaba 插件,解决代码中的规范问题.再研究一下Code菜单,找出一项让自己感觉最好用的功能. 在码云上把自己的学习搭档加入自己的项目中,确认 ...
- jlet
项目地址 : https://github.com/kelin-xycs/jlet jlet jlet 一个 javascript 的 小 Lib 本来想写一个 javascript 的 小 Lib ...
- mysql悲观锁
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念. 悲观锁(Pessimistic Lock) 悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能 ...
- Day 12 开放封闭原则,装饰器初识
nonlocal关键字 # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值# 案例:def outer(): n ...