Muduo 网络编程示例

我将会写一系列文章,介绍用 muduo 网络库完成常见的 TCP 网络编程任务。目前计划如下:

UNP 中的简单协议,包括 echo、daytime、time、discard 等。 

Boost.Asio 中的示例, 包括 timer2~6、chat 等。

Java Netty 中的示例,包括 discard、echo、uptime 等,其中的 discard 和 echo 带流量统计功能。

Python twisted 中的示例,包括 finger01~07

用于测试两台机器的往返延迟的 roundtrip

用于测试两台机器的带宽的 pingpong

云风的串并转换连接服务器  multiplexer,包括单线程和多线程两个版本。

文件传输

一个基于 TCP 的应用层广播 hub

socks4a 代理服务器,包括简单的 TCP 中继(relay)。

一个 Sudoku 服务器的演变,从单线程到多线程,从阻塞到 event-based。

一个提供短址服务的 httpd 服务器

其中前面 7 个已经放到了 muduo 代码的 examples 目录中,下载地址是: http://muduo.googlecode.com/files/muduo-0.1.5-alpha.tar.gz 

这些例子都比较简单,逻辑不复杂,代码也很短,适合摘取关键部分放到博客上。其中一些有 一定的代表性与针对性,比如“如何传输完整的文件”估计是网络编程的初学者经常遇到的 问题。请注意,muduo 是设计来开发内网的网络程序,它没有做任何安全方面的加强措施,如果用在公 网上可能会受到攻击,在后面的例子中我会谈到这一点。

本系列文章适用于 Linux 2.6.x (x > 28),主要测试发行版为 Ubuntu 10.04 LTS 和 Debian 6.0 Squeeze,64-bit x86 硬件。

TCP 网络编程本质论

我认为,TCP 网络编程最本质的是处理三个半事件:

连接的建 立,包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接。

连接的断开,包 括主动断开 (close 或 shutdown) 和被动断开 (read 返回 0)。

消息到达,文件描述符可读 。这是最为重要的一个事件,对它的处理方式决定了网络编程的风格(阻塞还是非阻塞,如何处理分包 ,应用层的缓冲如何设计等等)。

消息发送完毕,这算半个。对于低流量的服务,可以不必关 心这个事件;另外,这里“发送完毕”是指将数据写入操作系统的缓冲区,将由 TCP 协议 栈负责数据的发送与重传,不代表对方已经收到数据。

这其中有很多难点,也有很多细节需要注意,比方说:

如果要主动关闭连接,如何保证对方 已经收到全部数据?如果应用层有缓冲(这在非阻塞网络编程中是必须的,见下文),那么如何保证先 发送完缓冲区中的数据,然后再断开连接。直接调用 close(2) 恐怕是不行的。

如果主动发起 连接,但是对方主动拒绝,如何定期 (带 back-off) 重试?

非阻塞网络编程该用边沿触发 (edge trigger)还是电平触发(level trigger)?(这两个中文术语有其他译法,我选择了一个电子工 程师熟悉的说法。)如果是电平触发,那么什么时候关注 EPOLLOUT 事件?会不会造成 busy-loop?如 果是边沿触发,如何防止漏读造成的饥饿?epoll 一定比 poll 快吗?

时间: 2024-12-06 05:22:12

Muduo 网络编程示例的相关文章

Muduo 网络编程示例(六)限制服务器的最大并发连接数

本文已以大家都熟悉的 EchoServer 介绍如何限制服务器的并发连接数. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/maxconnection/ <Muduo 网络 编程示例 系列>计划中的第六篇文章原本是"用于测试两台机器的带宽的 pingpong 程序", pingpong 协议的程序已经在<muduo 与 boost asio 吞吐量对比>和<muduo

Muduo 网络编程示例之零:前言

陈硕 (giantchen_AT_gmail)Blog.csdn.net/Solstice Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/779646.aspx我将会写一系列文章,介绍用 muduo 网络库完成常见的 TCP 网络编程任务.目前计划如下: UNP 中的简单协议,包括 echo.daytime.time.discard 等.  Boost.Asio 中的示例,包括 timer2~6.chat 等. Java Netty 

Muduo 网络编程示例(二) Boost.Asio 的聊天服务器

本文讲介绍一个与 Boost.Asio 的示例代码中的聊天服务器功能类似的网络服务程序,包括客户端 与服务端的 muduo 实现.这个例子的主要目的是介绍如何处理分包,并初步涉及 Muduo 的多线程功能 .Muduo 的下载地址: http://muduo.googlecode.com/files/muduo-0.1.7-alpha.tar.gz ,SHA1 873567e43b3c2cae592101ea809b30ba730f2ee6,本文的完整代码可在线阅读 http://code.go

Muduo 网络编程示例(九)简单的消息广播服务

本文介绍用 muduo 实现一个简单的 topic-based 消息广播服务,这其实是"聊天室"的一个简单 扩展,不过聊天的不是人,而是分布式系统中的程序. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/hub 在分布式系统中,除了常用的 end-to-end 通信,还有一对多的广播通信.一提到"广播",或许 会让人联想到 IP 多播或 IP 组播,这不是本文的主题.本文将要谈的

Muduo 网络编程示例(七)“串并转换”连接服务器及其自动化测试

本文介绍如何使用 test harness 来测试一个具有内部逻辑的网络服务程序. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer 下载地址: http://muduo.googlecode.com/files/muduo-0.2.0-alpha.tar.gz SHA1 checksum: 75a09a82f96b583004876e95105c679e64c95715 云风在他的博客中

Muduo 网络编程示例(四)Twisted Finger

Python Twisted 是一款非常好的网络库,它也采用 Reactor 作为网络编程的基本模型,所以从使 用上与 muduo 颇有相似之处.(当然,muduo 没有 deferreds)Finger 是 twisted 文档的一个经典 例子,本文展示如何用 muduo 来实现最简单的 finger 服务端.限于篇幅,只实现 finger01~07.代 码位于 examples/twisted/finger . 1 拒绝连接 什么都不做,程序空等. finger01.cc 1: #inclu

Muduo 网络编程示例(五)测量两台机器的网络延迟

本文介绍一个简单的网络程序 roundtrip,用于测量两台机器之间的网络延迟,即"往返时间 / round trip time / RTT".这篇文章主要考察定长 TCP 消息的分包,TCP_NODELAY 的作用. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/roundtrip/roundtrip.cc 测量 RTT 的办法很简单: host A 发一条消息给 host B,其中包含 host

Muduo 网络编程示例(一) 五个简单TCP协议

本文将介绍第一个示例:五个简单 TCP 网络服务协议,包括 echo (RFC 862).discard (RFC 863) .chargen (RFC 864).daytime (RFC 867).time (RFC 868),以及 time 协议的客户端.各协议的功 能简介如下: * discard - 丢弃所有收到的数据: * daytime - 服务端 accept 连接之 后,以字符串形式发送当前时间,然后主动断开连接: * time - 服务端 accept 连接之后,以 二进制形式

Muduo 网络编程示例(十)socks4a 代理服务器

本文介绍用 muduo 实现一个简单的 socks4a 代理服务器,代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/socks4a/ . TCP 中继器 在实现 socks4a proxy 之前,我们先写一个功能更简单的网络程序-- TCP 中继器 (TCP relay),或者叫做穷人的 tcpdump (poor man's tcpdump). 一般情况下,客户端程序直接 连接服务端,如下图.有时候,我们想在 cl