网络编程实战
盛延敏
前大众点评云平台首席架构师
立即订阅
6034 人已学习
课程目录
已完结 39 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 学好网络编程,需要掌握哪些核心问题?
免费
第一模块:基础篇 (9讲)
01 | 追古溯源:TCP/IP和Linux是如何改变世界的?
02 | 网络编程模型:认识客户端-服务器网络模型的基本概念
03丨套接字和地址:像电话和电话号码一样理解它们
04 | TCP三次握手:怎么使用套接字格式建立连接?
05 | 使用套接字进行读写:开始交流吧
06 | 嗨,别忘了UDP这个小兄弟
07 | What? 还有本地套接字?
08 | 工欲善其事必先利其器:学会使用各种工具
09丨答疑篇:学习网络编程前,需要准备哪些东西?
第二模块:提高篇 (10讲)
10 | TIME_WAIT:隐藏在细节下的魔鬼
11 | 优雅地关闭还是粗暴地关闭 ?
12 | 连接无效:使用Keep-Alive还是应用心跳来检测?
13 | 小数据包应对之策:理解TCP协议中的动态数据传输
14丨UDP也可以是“已连接”?
15 | 怎么老是出现“地址已经被使用”?
16 | 如何理解TCP的“流”?
17 | TCP并不总是“可靠”的?
18 | 防人之心不可无:检查数据的有效性
19丨提高篇答疑:如何理解TCP四次挥手?
期中复习周 (2讲)
期中大作业丨动手编写一个自己的程序吧!
免费
期中大作业丨题目以及解答剖析
免费
第三模块:性能篇 (12讲)
20 | 大名⿍⿍的select:看我如何同时感知多个I/O事件
21 | poll:另一种I/O多路复用
22 | 非阻塞I/O:提升性能的加速器
23 | Linux利器:epoll的前世今生
24 | C10K问题:高并发模型设计
25 | 使用阻塞I/O和进程模型:最传统的方式
26 | 使用阻塞I/O和线程模型:换一种轻量的方式
27 | I/O多路复用遇上线程:使用poll单线程处理所有I/O事件
28 | I/O多路复用进阶:子线程使用poll处理连接I/O事件
29 | 渐入佳境:使用epoll和多线程模型
30 | 真正的大杀器:异步I/O探索
31丨性能篇答疑:epoll源码深度剖析
第四模块:实战篇 (4讲)
32 | 自己动手写高性能HTTP服务器(一):设计和思路
33 | 自己动手写高性能HTTP服务器(二):I/O模型和多线程模型实现
34 | 自己动手写高性能HTTP服务器(三):TCP字节流处理和HTTP协议实现
35 | 答疑:编写高性能网络编程框架时,都需要注意哪些问题?
结束语 (1讲)
结束语丨我相信这不是结束,让我们江湖再见
网络编程实战
登录|注册

06 | 嗨,别忘了UDP这个小兄弟

盛延敏 2019-08-14
你好,我是盛延敏,这里是网络编程实战第 6 讲,欢迎回来。
前面几讲我们讲述了 TCP 方面的编程知识,这一讲我们来讲讲 UDP 方面的编程知识。
如果说 TCP 是网络协议的“大哥”,那么 UDP 可以说是“小兄弟”。这个小兄弟和大哥比,有什么差异呢?
首先,UDP 是一种“数据报”协议,而 TCP 是一种面向连接的“数据流”协议。
TCP 可以用日常生活中打电话的场景打比方,前面也多次用到了这样的例子。在这个例子中,拨打号码,接通电话,开始交流,分别对应了 TCP 的三次握手和报文传送。一旦双方的连接建立,那么双方对话时,一定知道彼此是谁。这个时候我们就说,这种对话是有上下文的。
同样的,我们也可以给 UDP 找一个类似的例子,这个例子就是邮寄明信片。在这个例子中,发信方在明信片中填上了接收方的地址和邮编,投递到邮局的邮筒之后,就可以不管了。发信方也可以给这个接收方再邮寄第二张、第三张,甚至是第四张明信片,但是这几张明信片之间是没有任何关系的,他们的到达顺序也是不保证的,有可能最后寄出的第四张明信片最先到达接收者的手中,因为没有序号,接收者也不知道这是第四张寄出的明信片;而且,即使接收方没有收到明信片,也没有办法重新邮寄一遍该明信片。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《网络编程实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(29)

  • 许童童
    第一个场景中,可以添加超时时间做处理,当然你也可以自己实现一个复杂的请求-确认模式,那这样就跟TCP类似了,HTTP/3就是这样做的。

    用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) - UDP头(8)=65507字节。用sendto函数发送数据时,如果发送数据长度大于该值,则函数会返回错误。
    由于IP有最大MTU,因此,
    UDP 包的大小应该是 1500 - IP头(20) - UDP头(8) = 1472(Bytes)
    TCP 包的大小应该是 1500 - IP头(20) - TCP头(20) = 1460 (Bytes)
    2019-08-14
    3
    36
  • 刘明
    1、一直阻塞会导致程序无法正常退出,可以使用接收超时、IO多路复用的超时机制。

    2、IP和UDP头中都有16bit的长度字段,最长65535字节,去掉头部长度得到UDP数据净荷长度:65535-20-8=65507字节。
    2019-08-14
    1
    8
  • 范龙dragon
    客户端代码的29行sendline数组之前没有初始化数组元素为0,直接用strlen应该会有问题吧,strlen不是以0作为结束标志吗?

    作者回复: 好问题,fgets函数会"默默"的给我们加上\0

    2019-08-18
    3
  • 江永枫
    关于阻塞io,可以考虑使用多线程模型去提升性能,或者结合io多路复用来处理能力。


    https://m.php.cn/article/410029.html

    作者回复: 很快就会讲到了 :)

    2019-08-14
    2
  • Godblesser
    recvfrom函数可以设置超时,当限定时间内未接收到服务器端回复,打印超时消息并退出
    2019-08-14
    2
  • 记事本
    recv from会导致进程一直阻塞,可以通过setsocketopt接口设置TIMEOUT 超时后退出.
    2019-08-14
    2
  • 你好
    多人聊天室使用UDP,消息发出后怎么保证消息可以被收到呀,UDP不是不可靠传输嘛,中间丢了消息咋办呀

    作者回复: 第一,丢了就丢了,反正UDP就是不可靠的;

    第二,给每条消息加个sequence,收到后再确认,一段时间内没收到,就重发。

    2019-10-30
    2
    1
  • tongmin_tsai
    老师,UDP被IP层分包发送后,对端如何保证UDP包整个组合的?比如用UDP发送3000字节,假设拆分2个MTU发送,后一个先到服务端,前一个后到服务端,那应用层接收的时候,UDP怎么组装的?

    作者回复: 很简单,1-1500为一个seq=1的包,1501-3000为seq=2的包,根据sequence组装就可以了。

    2019-09-30
    1
  • 云端
    老师您好:
    阻塞=进程或线程挂起?

    作者回复: 是的。

    2019-09-22
    1
  • 破晓^_^
    函数sendto原型参数写错了,应该为ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags,const struct sockaddr *to, socklen_t addrlen); 最后一个参数与recvfrom不一样.

    作者回复: 笔误,感谢斧正,我来修正。

    2019-09-10
    1
  • kissingers
    老师,TCP 流,UDP包,流的说法怎么理解?

    作者回复: 流就像水流,一直持续不断的流淌,只不过流淌的是0101这样的比特流。

    2019-09-06
    1
    1
  • 马留
    如果对udp套接字调用了listen函数,会怎么样呢?

    作者回复: 改下程序,试试就知道了,最好把你的结果贴上来,大家一起研究。

    2019-08-29
    2
    1
  • 奔奔奔跑
    老师,学完这章我有个不理解的地方,UDP是客户端向服务端发消息,服务端收到客户端的报文,根据报文的地址在传消息回去,因此服务端不能主动向客户端发消息。那么客户端如果也bind,那么服务端也能向客户端发消息了,老师我这么理解对吗

    作者回复: 那走的就是两条不同的连接了
    A-->B
    B-->A

    2019-11-23
    1
  • godtrue
    小结
    1:UDP是一个不可靠的通信协议,没有重传和确认,没有有序控制,也没有拥塞控制。
    2:UDP 不保证报文的有效传递,不保证报文的有序,也就是说使用 UDP 的时候,我们需要做好丢包、重传、报文组装等工作。
    3: UDP 相对TCP比较简单,适合的场景还是比较多的,我们常见的 DNS 服务,SNMP 服务都是基于 UDP 协议的,这些场景对时延、丢包都不是特别敏感。另外多人通信的场景,如聊天室、多人游戏等,也都会使用到 UDP 协议。
    4:把UDP协议比做发生明信片确实生动形象,我告诉邮局送到那些地址,具体送到没有,需要接收端主动的响应(注意:这里的响应者更靠上层)协议本身不会进行重传/确认/时序/拥塞等控制。
    2019-11-22
  • 流浪在寂寞古城
    https://github.com/worsun/study/tree/master/hack_time/socket_code/6
    自己敲了可以运行的代码
    2019-10-31
  • 流浪在寂寞古城
    https://github.com/worsun/study/tree/master/hack_time/socket_code/6

    作者回复: 👍

    2019-10-31
  • LY.
    lib/common.h里面的内容从哪可以找到啊?

    作者回复: https://github.com/froghui/yolanda/tree/master/lib

    2019-10-28
  • 董尚斌
    第一个案例中,UDP客户端为啥要等响应呢?不是说丢出去就不管了吗。那相应的内容是啥呢?

    作者回复: UDP只是说是一个非面向连接的协议,在双方通信过程中,是需要互相发送报文,以便响应的,就像是一个基于UDP的聊天室,你看到别人的消息,也需要回一个消息,不同消息的内容就是响应的内容。

    2019-10-28
  • haozhang
    服务器代码中的message[n]='\0'吧

    作者回复: 应该是一个意思。

    2019-10-19
  • 禾桃
    “另外,既然 UDP 是请求 - 应答模式的,那么请求中的 UDP 报文最大可以是多大呢?”

    大小感觉没有限制吧,如果用户数据>
    (链路网络设备最小的IP_MTU - UDPHeaderSize -IPHeaderSize), IP层会把用户数据分割成多个IP Fragments, 通过多个网络包传输出去,接收点的IP层把这些Fragmengs组装好,返还给用户?

    作者回复: 嗯,我说的是和MTU有关系的,从应用层来说,报文被分割以后,当然可以认为是大小无限制。

    2019-08-19
收起评论
29
返回
顶部