1       案例背景

在学习TCP-IP协议详解卷一时,读到介绍TCP协议的部分,发现TCP的首部是没有报文总长度字段的,而在UDP中是有的,对这个问题的思考引出了两者之间的区别。

2    案例分析

TCP报文的格式:

TCP首部的格式:

UDP报文的格式:

UDP首部的格式:

针对首部公共部分的对比,很明显的一个区别是UDP首部是有数据报总长度字段的,而TCP首部是没有数据报总长度字段的,这个原因的解释在TCP-IP详解卷一答案中的解释是TCP首部有选项字段而UDP首部大小是固定的,而网上的查询结果有一种是因为模式的不同。

我比较赞同的是,TCP是面向连接的流模式,而UDP是不连接的数据报模式。

3       实验

实验一:

TCP客户端循环发送数据到服务器,主循环部分分三次调用send或者sendto,分别发送111,222,333;而服务器是睡眠十秒,然后调用recv或者recvfrom接收数据。注意,只接收一次。

客户端发送部分(其中的sendto可用send代替):

while(1)

{

memset(achBuf,0,1024);

memcpy(achBuf,"111",3);

buflen = strlen(achBuf);

ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));

memset(achBuf,0,1024);

memcpy(achBuf,"222",3);

buflen = strlen(achBuf);

ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));

memset(achBuf,0,1024);

memcpy(achBuf,"333",3);

buflen = strlen(achBuf);

ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));

}

服务器接收部分(其中的recv可用recvfrom代替):

sleep(10);

recv(conn,buf,1024,0);

printf("conn = %s\n",buf);

四种不同的发送接收组合,均是以下结果:

实验二:

UDP客户端循环发送数据到服务器,分三次调用sendto,分别发送了111,222,333;服务器睡眠十秒,然后调用recvfrom循环接收数据。为了表示是第几次接收到的数据,首先打印接收序号。

客户端发送部分:

nNum = sendto(nSockFd,"111\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));

printf("nNum = %d\n",nNum);

nNum = sendto(nSockFd,"222\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));

printf("nNum = %d\n",nNum);

nNum = sendto(nSockFd,"333\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));

printf("nNum = %d\n",nNum);

服务器接收部分:

while(1)

{

sleep(10);

memset(achBuf,0,MAXBUFLEN);

nNum = recvfrom(nServFd,achBuf,MAXBUFLEN,0,(struct sockaddr *)&CliAddr, &dwCliAddrLen);

if(nNum < 0)

{

printf("recverror\n");

break;

}

printf("%d\n",i);i++;

printf("%s\n",achBuf);

}

结果如下图:

4       总结

由实验结果可以知道,读取数据的方式和调用的函数没有关系,而和套接字类型有关。而TCP接收数据时不是一次只读取一个数据报,而是根据buf的大小和缓冲区数据的大小中的较小值来读取数据的,可以一次性读取多个数据报;而UDP是按照接收到的数据次序,一次只读取一个数据报。

现在可以大概的推敲出流模式和数据报模式的区别,接收和发送数据方式的不同。流模式只要不超过流的容量就可以继续往流上提交数据,另一端只要流上有数据就可以读取,而不管这个数据的开头和结尾;数据报模式,有严格的次序关系和数据报的分割关系。而这两种的不同大概是由于TCP一个套接字只接收来自一个对象的数据,而UDP套接字可以接收来自任意对象的数据。

两者在模式上的不同,导致两者在效率和应用模式上的不同。

在每个数据都要分析的情况下,例如发送一条配置命令,TCP必须约定消息头格式指出这条消息的大小,而UDP不需要。而在流媒体数据上,由于TCP有数据重组的特性,效率相对UDP更高。

TCP的流模式与UDP的报文模式对比的更多相关文章

  1. TCP 流模式与UDP数据报模式(转)

    TCP流模式与UDP数据报模式http://blog.csdn.net/s3olo/article/details/7914717 数据报(datagram)通常是指起始点和目的地都使用无连接网络服务 ...

  2. Kcptun 是一个非常简单和快速的,基于KCP 协议的UDP 隧道,它可以将TCP 流转换为KCP+UDP 流

    本博客曾经发布了通过 Finalspeed 加速 Shadowsocks 的教程,大家普遍反映能达到一个非常不错的速度.Finalspeed 虽好,就是内存占用稍高,不适合服务器内存本来就小的用户:而 ...

  3. TCP面向字节流和UDP面向报文的区别

    TCP面向字节流 打个比方比喻TCP,你家里有个蓄水池,你可以里面倒水,蓄水池上有个龙头,你可以通过龙头将水池里的水放出来,然后用各种各样的容器装(杯子.矿泉水瓶.锅碗瓢盆)接水. 上面的例子中,往水 ...

  4. TCP/IP协议中的UDP与TCP的区别

    TCP面向连接,UDP面向非连接即发送数据前不需要建立链接TCP提供可靠的服务(数据传输),UDP无法保证,它没有TCP的接受确认.窗口等机制,因此也不需要交换控制信息:发生丢包也一概不负责.TCP面 ...

  5. python网络编程--TCP连接的三次握手(三报文握手)与四次挥手

    一.TCP连接 运输连接有三个阶段: 连接建立.数据传送和连接释放. 在TCP连接建立过程中要解决以下三个问题: 1,要使每一方能够确知对方的存在. 2.要允许双方协商一些参数(如最大窗口之,是否使用 ...

  6. 10 TCP限流技术

    TCP限流是因为让接收方充分接受完消息,保证数据安全,不会丢失 一.窗口机制介绍 发送端和接收端都拥有一个窗口,当发送端发送数据时,落进窗口的数据被发送,当接受端接受数据时,落进接收端窗口的数据将会被 ...

  7. threaded模式下,比prefork模式要省资源

    关于nginx + fastcgi + django 2009-03-10 17:14:43 分类: 系统运维 最近用django开发了一套广告投放系统,这套系统其实是一套网络广告联盟系统,包括广告的 ...

  8. redis-3.28 一主二从模式介绍、主从从模式介绍、sentinel模式一主两从高可用

    一.redis-3.28部署 yum install gcc tclwget http://download.redis.io/releases/redis-3.2.8.tar.gztar -zxvf ...

  9. 设计模式GOF23(结构型模式:代理模式,适配模式,桥接模式,组合模式,装饰模式,外观模式,享元模式)

    结构型模式: – 分类: • 适配器模式.代理模式.桥接模式.装饰模式.组合模式.外观模式.享元模式 – 核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题.   结构 ...

随机推荐

  1. 洛谷P2746 [USACO5.3]校园网Network of Schools

    题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要写 ...

  2. Mysql: ERROR 1030 (HY000): Got error 28 from storage engine

    今天帮同事解决一个问题的时候,遇到了下面的异常: ERROR 1030 (HY000): Got error 28 from storage engine 我们的数据库是mysql,我们的sql语句是 ...

  3. CF 115B Lawnmower(贪心)

    题目链接: 传送门 Lawnmower time limit per test:2 second     memory limit per test:256 megabytes Description ...

  4. [Android]加密技术

    对称加密无论是加密还是解密都使用同一个key,而非对称加密需要两个key(public key和private key).使用public key对数据进行加密,必须使用private key对数据进 ...

  5. 一起买beta版模块单元测试

    一起买beta版模块接口单元测试 测试目的 保证代码质量,对各个模块进行单元测试,不仅可以有效地保证代码的可靠性,让模块在与别的模块整合时出现更少的错误. 而且不用每次启动程序而等待浪费时间. 单元描 ...

  6. 深入理解javascript中执行环境(作用域)与作用域链

    深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...

  7. JS010-DOM

    JS010-DOM 本章内容: 1.理解包含不同层次节点的DOM 2.使用不同的节点类型 3.客服浏览器兼容性问题及各种陷阱 DOM(文档对象模型)是针对 HTML和xml文旦过得一个API(应用程序 ...

  8. context.Request.Files为NULL问题 在实现图片上传功能的时候出现在ashx等处理页面出现context.Request.Files为NULL异常,有几点需要注意:

    .在客户端可以将form用submit提交,如下: <%@ Page Language="C#" AutoEventWireup="true" CodeF ...

  9. bootstrap panel 和table的使用

    一.HTML中的页面内容 <div class="col-sm-12"> <!-- <div class="m-b-md" style= ...

  10. C++中public,protected,private派生类继承问题和访问权限问题

    C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...