body
{
font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif;
font-size: 10.5pt;
line-height: 1.5;
}
html, body
{

}
h1 {
font-size:1.5em;
font-weight:bold;
}
h2 {
font-size:1.4em;
font-weight:bold;
}
h3 {
font-size:1.3em;
font-weight:bold;
}
h4 {
font-size:1.2em;
font-weight:bold;
}
h5 {
font-size:1.1em;
font-weight:bold;
}
h6 {
font-size:1.0em;
font-weight:bold;
}
img {
border:0;
max-width: 100%;
height: auto !important;
}
blockquote {
margin-top:0px;
margin-bottom:0px;
}
table {
border-collapse:collapse;
border:1px solid #bbbbbb;
}
td {
border-collapse:collapse;
border:1px solid #bbbbbb;
}

[原]TCP/UDP使用细节备忘

首先,TCP和UDP的基本区别是TCP提供可靠的面向连接的流传输;UDP提供不可靠的基于数据包的传输;

所谓可靠就是说发送端调用send后,数据就一定会发送给接收端。虽然这当中可能会消耗很长的时间,或者实在无法发送的话发送端或者接收端也能得到适当的通知。而不可靠传输是指,发送端调用send后,接收端能不能收到数据是没有保证的,运气(网络状况)好的话,接收端可以立即收到数据。运气不好的话,数据可能会在传输过程中被丢弃。如果数据被丢弃的话,发送端和接收端都不会得到任何通知。另外,数据还有可能经历漫长的时间后到达接收端。

那么基于流的传输是指发送端send一块数据后,就像把一杯水倒入小河,当水流到达接收端后,接收端能够汲取到从发送端传过来的水,那却很难再把那杯水原原本本地装进一个杯子里了(当然实际的开发中,可以在这块数据前后设置标志让接收端从流中提取出这块数据来)。正因为TCP的传输是基于流的,所以发送端调用N次send总共发送S字节的数据,在接收端对应的是M次recv总共接收的数据还是S字节。这里N往往不等于M,如果实际使用中希望send的数据块和recv的数据块的次数对等的话,就要自己给数据块加上标志以帮助接收端区分数据块。而且在接收端区分数据块是也很可能发生一次recv从流中接收的数据不够一块的情况,这时,接收端应该等待TCP流再次到达,并从中recv块剩余的部分。

基于数据包的传输和流不一样,发送端send一块数据后,如果数据能够到达接收端,那么接收端recv到的就是一块完整的数据。如果数据包丢失,那么接收端就收不到任何东西。所以对于UDP的数据包传输来说,情况很简单,接收端要么收到完整的数据包,要么啥都收不到。数据包和数据流另外一个不同点是,数据流中的数据是有序的,接收端收到的数据和发送端发送的数据的顺序是一致的。而数据包的数据不能保证有序,发送端发送的数据到达接收端的顺序是错乱的。

相较之下,UDP的概念比TCP要简洁一些,但是实际使用起来,要注意的地方也要更多一些。所以在使用UDP时要注意以下几个方面:

1)UDP不提供拥塞控制,如果发送端无节制地向接收端发送数据包,很可能会导致接收端来不及处理数据包,而造成大量的丢包现象。

2)UDP的数据包是无序的,接收端如果对数据的顺序有要求的话,要自行处理数据包的顺序

3)UDP数据包的大小是有限制的,理论上这个限制是由于一个IP包的最大长度除去UDP包头的长度,而实际上各个不同的TCP/IP协议的实现给出的限制不同,基本都小于32768。而实际的网络环境中,往往要更小。

除了上面提到过的UDP数据包的大小限制,还有一个MTU的概念,MTU基本上是由于链路层协议对数据包的长度的限制,不同的链路层的MTU是不一样的,如果一个IP数据包的长度超过了链路的MTU,那么这个包会按MTU的大小在链路层分片,当数据通过链路后,再重新组包后发送到IP的下一路。在一个IP包的传输过程中可能会发生多次分片和组包。如果一个IP包中设置了禁止分片的DF标志,那么,当发现IP包的长度超过MTU时,数据包会被丢弃。发送端会收到一个ICMP的通知,告诉数据包因为过大而被丢弃。看起来,MTU和UDP数据包大小限制这两个概念比较容易搞混淆。其实MTU是一个影响IP层的概念,而UDP数据包大小限制是传输层的问题。假设发送端和接收端之间的MTU是1500,这并不代表UDP包的最大限制就是1500。此时UDP包的最大限制还可能是32768!这是因为承载UDP包的IP包在网络上自动被分片并组包了。这个情况下UDP包的最大限制是由TCP/IP协议的实现决定的,如果这个实现的IP包都设置DF标志,那么IP包在链路上不会被分片,那么UDP的最大限制就等于MTU,是1500。如果这个实现的IP包不设置DF标志,那么IP包在链路上就能顺序通过,那就由这个实现中对UDP的大小限制这个部分来决定了。

最后,TCP会自己处理每个TCP数据段的大小(MSS),UDP的最大限制就要使用者自己来把握(可以使用比较保险的较小的值,也可以通过在发送端和接收端之间发送检测包来决定)。还有,当数据无法发送到接收端时(往往是接收端的进程并没有启动),TCP和UDP都能收到适当的通过。在socket当中都是10053这个错误号,在TCP的实现中,是通过设置了RST标志的包通知,在UDP的实现中,是通过一个ICMP包来通知的。

作者:nobugtodebug 发表于2010-12-17 11:12:00 原文链接
阅读:119 评论:0 查看评论

[原]TCP/UDP使用细节备忘的更多相关文章

  1. Python 小细节备忘

    1. 多行字符串可以通过三个连续的单引号 (”’) 或是双引号 (“”") 来进行标示 >>> a='''a bc def ''' >>> print a ...

  2. [原][JSBSim]基于qt代码实现:TCP|UDP与飞行模拟软件JSBSim的通信,现实模型飞行!

    废话没有,上关键代码 头文件 #include <QUdpSocket> #include <qtcpsocket.h> #ifndef vrUDP #define vrUDP ...

  3. Nmap备忘单:从探索到漏洞利用(Part 2)

    这是我们的第二期NMAP备忘单(第一期在此).基本上,我们将讨论一些高级NMAP扫描的技术,我们将进行一个中间人攻击(MITM).现在,游戏开始了. TCP SYN扫描 SYN扫描是默认的且最流行的扫 ...

  4. 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP

    继续来做(da)推(guang)介(gao)我自己的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,目前已完成 ...

  5. linux 指令备忘

    linux 指令备忘 1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件 -A 通-a,但不列出"."和"..& ...

  6. CentOS6.4 X86_64 kvm+PXE备忘

    Install 安装 1 2 3 4 5 # yum install qemu-kvm qemu-img # 使用kvm至少要安装的包,一个提供用户级别kvm模拟器,一个提供磁盘镜像的管理 # 安装虚 ...

  7. 高性能 TCP & UDP 通信框架 HP-Socket v3.3.1

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  8. 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  9. 高性能 TCP & UDP 通信框架 HP-Socket v3.2.2 正式发布

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

随机推荐

  1. js获取和设置DOM样式函数cssStyle(类似于jquery的$(elem).css())

    如题,相信这个函数百度一搜一大推,但令人匪夷所思的是这些函数都写的“奇形怪状的”,例如http://www.cnblogs.com/windows7/archive/2010/03/30/170064 ...

  2. luigi学习5-task详解

    task是代码执行的地方.task通过target互相依赖. 下面是一个典型的task的大纲视图. 一.Task.requires requires方法用来指定本task的依赖的其他task对象,依赖 ...

  3. 添加Microsoft SQL JDBC driver 到 Maven

    主要步骤如下: 1. 本地下载sqljdbc4.jar 2. 解压到本地文件夹中,并找到sqljdbc4.jar路径 3. 打开命令窗口,打开至工程目录,执行以下语句(前提:先配置好maven环境变量 ...

  4. phpcms后台部分修改

    1.后台登陆前提示信息取消及成功后提示信息取消.    (1)后台登陆前提示信息取消               phpcms\modules\admin\classes\admin.class.ph ...

  5. windows下编译lua源码

    所有的lua源码都放在了 src 文件夹下,当然,不同的lua版本目录结构有可能不一样,但是都会有 src 这个文件夹,只有这个才是我们编译必须的.而且lua越做越精简了,5.1的版本里面还有一些te ...

  6. 配置github上的SSH key及上传自己的项目到github

    这篇文章比较好,链接如下:http://www.jianshu.com/p/b81eeb5d7858 需要指出的几点:1.

  7. NLP自然语言处理学习笔记三(集成开发环境)

    前言: 我们在做自然语言学习的过程中使用Python进行编程.是用解析器的方式确实有些麻烦.在这里给大家推荐一款集成开发环境IDE可以很方便的对Python进行项目管理,代码自动提示,运行调试等. 简 ...

  8. python 遍历文件夹

    import os import os.path rootdir = “d:\data” # 指明被遍历的文件夹 for parent,dirnames,filenames in os.walk(ro ...

  9. chrome下的js调试

    console输出对象信息:console.log(object[,object,.....])

  10. Swift 类构造器的使用

    Swift 中构造器需要遵循的规则还是很多的, 总结一下, 有以下规则: 调用相关 指定构造器必须调用它直接父类的指定构造器方法. 便利构造器必须调用同一个类中定义的其它初始化方法. 便利构造器在最后 ...