• 2015-07-16

    经典的 TCP socket 读取报文错误

    Views: 10411 | 5 Comments

    面试了很多做了多年网络编程的人, 从TCP socket中读取报文这项基本技能, 许多人都做不对. 经典的错误用法是:

    char buf[1024]; // 1024或者更大
    read(sock, buf, sizeof(buf));
    if(parse(buf) == 1){
        // 报文解析完毕
    }else{
        // 不是一个完整的报文, 丢弃
    }
    

    这是非常经典的错误! 没有任何文档或者手册表明, read()会读到*完整*的报文, 对于read()函数来说, 它只知道字节流, 不知"报文"为何物. read()可能只读到了1个字节的数据就返回... 而且, read()返回的数据的长度, 和对方write()不是一一对应的. 对方调用1次write(), 可能本方要调用1次或者2次或者更多次read().

    这个错误之所以经典, 是因为在局域网条件下, 且报文非常小的情况下, 一般(仅仅是一般, 不是100%)write()和read()是一一对应的, 所以, 有些人即使是在BAT公司写了10年网络编程, 也发现不了这个错误. 这个错误就是所谓的"TCP粘包/断包".

    看看这个PDF: 高性能并发网络服务器设计与实现.pdf, 看看如何正确地从TCP socket中读取报文. 或者看看 Sim C++ 框架的源码, 了解下 Sim 是如何从 TCP socket 中读取一个报文: https://github.com/ideawu/sim/blob/master/src/server.cpp#L143

    Posted by ideawu at 2015-07-16 16:41:23
  • 2015-05-18

    简单的 C++ 网络服务框架 Sim 介绍

    Views: 9189 | 5 Comments

    可测性

    Sim 采用了一种极简的报文格式, 在你没有开始写 Client 时, 你就可以利用手上现成的工具, 如 nc, telnet 来测试. 可测性非常重要, 你可以随时查看代码的执行效果, 这对开发者的心理会产生非常正面的促进作用. 即使你不想使用 nc 这样的命令, 你想写 PHP 或者 Python 脚本, 也是非常简单的.

    例如, 你采用 Sim 框架写了一个计算加法的服务器. 这时怎么测试呢? 很简单! 在命令行执行

    $ nc 127.0.0.1 8800
    add 1 3
    ok 4
    

    随时随地地通过实际的输入和输出来测试程序, 会让程序员的心理更愉悦. 如果通过枯燥的单元测试, 进行大量参数配置, 只会让人心慌, 影响开发效率.

    内置 Log/Config 工具

    Sim 采用了 SSDB 项目的日志和配置代码, 让你的服务器立即就拥有日志输出功能和可配置性. 日志非常重要, 我几乎不使用 gdb 这样底层的调试工具. 有了 Config, 像修改端口这样的简单需求, 就不用再修改代码重新编译了.

    进程管理

    Sim 提供的工具可以让你的程序启动为后台进程, 不用借助 supervisor, nohup 这样的额外工具.

    关于性能

    记住, 不要一开始就关心性能, 计算机和 C++ 比你相像的要快得多!

    其它

    Sim 完全开源, 基于 New BSD 协议.

    项目地址: https://github.com/ideawu/sim

    Posted by ideawu at 2015-05-18 17:22:10
  • 2013-08-05

    WebRTC源码架构浅析

    Views: 38662 | No Comments

    Google 在2010年花了6千8百万美元收购了大名鼎鼎的 Global IP Sound/Solutions (GIPS) 公司, 得到了它的 VoIP 相关技术的专利和软件. 第二年, Google就把这些软件开源了, 不过, 不是作为独立的软件, 而且也和原来的软件功能大不一样, 而是作为所谓的 WebRTC 方案的一部分.

    GIPS 主要是提供视频和语音引擎技术和开发包, 而 WebRTC 却要提供一揽子的多媒体聊天解决方案, 特别是嵌入到浏览器中, 使用 Web 相关技术(如 JavaScript, HTML5). 所以, WebRTC 的源码结构非常庞大, 单单是从 trunk 中获取的代码和数据就达到1.2G还多.

    不过, 如果明白了 WebRTC 的架构, 就可以从这份开源代码中摘出我们想要的部分. WebRTC 包含下面几个部分:

    1. 应用层, 即 WebRTC 技术. 此部分的技术主要是浏览器开发者需要, 但因为其是太过于顶层的应用技术, 过于偏向某一方面, 所以可取可不取.

    2. 网络层, 主要是 libjingle. libjingle 就是 Google Talk 所使用的网络框架. 但 libjingle 并没开源服务器端的代码和技术, 再者, 网络层的可替换性很强, 各家公司总是设计自己的私有网络协议和架构, 所以, libjingle 的作用就是作为一个学习的对象.

    3. 语音和视频引擎, 这部分才是原来 GIPS 公司的专利和核心技术! 所以, 要详细解读一番.

    Continue reading »

    Posted by ideawu at 2013-08-05 00:24:01 Tags: , , , , ,
  • 2013-03-21

    高性能并发网络服务器设计与实现

    Views: 22231 | 4 Comments

    我在公司介绍的"高性能并发网络服务器设计与实现"PPT.

    看不着的朋友可以从这里下载: http://vdisk.weibo.com/s/dWpk2cal-1Zt

    Posted by ideawu at 2013-03-21 19:56:42
  • 2010-08-22

    Master-Workers 模式处理高负载

    Views: 22502 | 7 Comments

    对于高负载的网络服务器, 瓶颈几乎总是在等待 IO, 而 CPU 的计算能力往往不是最先遇到的问题. 你的服务器程序, 接收客户端的请求, 可能还要连接另一台网络服务器, 一起合作处理客户端的请求. 很多情况下, 你无法把客户端的连接以及与另一台服务器的连接统一处理, 不可避免地要出现等待. 这时, 只能使用多进程或者多线程.

    Master-Workers(管理者-工作者)模式是处理这种情况的主要方式, 只要有 IO 等待或者其它耗时的操作, 都交互若干个工作者之一处理, 这样, 后续的请求不会被阻塞, 从而实现高负载.

    目录:

    下文中有时用"进程"一词同时指代进程和线程, 它们的区别主要考虑的是通信方式.
    Continue reading »

    Posted by ideawu at 2010-08-22 16:03:57
  • 2010-07-16

    经典的”服务器最多65536个连接”误解

    Views: 32290 | 7 Comments

    "因为TCP端口号是16位无符号整数, 最大65535, 所以一台服务器最多支持65536个TCP socket连接." - 一个非常经典的误解! 即使是有多年网络编程经验的人, 也会持有这个错误结论.

    要戳破这个错误结论, 可以从理论和实践两方面来.

    理论

    系统通过一个四元组来唯一标识一条TCP连接. 这个四元组的结构是{local_ip, local_port, remote_ip, remote_port}, 对于IPv4, 系统理论上最多可以管理2^(32+16+32+16), 2的96次方个连接.

    因为对于同一台服务器来说, 一般只有一个 local_ip, 那么, 同一台服务器可以管理 2^(16+32+16) 个连接. 而一个服务(进程, 如 Nginx 进程)一般只监听一个 local_port, 那么, 同一台服务就可以管理 2^(32+16) 个连接. 而如果从一台远端机器(所谓的 client)来连接这台服务器上的一个服务, 那么 local_ip, local_port, remote_ip 这3个变量是固定的, 那么, 就只能建立 2^16=65536 个连接了. 这就是经典的误解的来源!

    如果不仅仅考虑TCP, 则是一个五元组, 加上协议号(TCP, UDP或者其它).

    Continue reading »

    Posted by ideawu at 2010-07-16 16:44:50
|<<<123456>>>| 1/6 Pages, 33 Results.