网络编程的一些简单总结

网络编程是一个很大也很有趣的话题,要写好一个高性能并且bug少的服务端或者客户端程序还是挺不容易的,而且往往涉及到进程线程管理/内存管理/VFS/协议栈等许多相关的知识,尤其是并发。所以不仅仅只是会使用socket那么简单。

网络编程模型

几个相关概念:

  • 阻塞/非阻塞
    阻塞和非阻塞通常是指文件描述符本身的属性,拿socket来说,当socket读缓冲区中没有数据时或者写缓冲区满时,都会造成我们read/recv或者write/send系统调用阻塞。而非阻塞socket在这种情况下会产生EWOULDBLOCK或者EAGAIN等错误并立即返回,不会等待socket变得可读或者可写。当然这只是理解阻塞和非阻塞的一个简单例子,并不全面。在Linux下我们可以通过accept4/fcntl等函数设置socket为非阻塞。
  • 同步/异步
    同步和异步可以分两层理解。一个是编程方式上的同步和异步,另一个是同步IO和异步IO。
    同步IO和异步IO更多地是我们怎么处理读写问题的一种手段。通常这也对应着两种高性能网络编程模式reactor和proactor,同步通常是我们主动读写数据,直到显示地返回读写状态标志;而异步通常是我们交给操作系统帮我们读写,只需要注册读写完成后的回调函数,提交完读写的请求控制权就返回到进程。
  • IO复用
    IO复用通常是用select/poll/epoll等来统一代理多个socket的事件的发生,select是一种比较通用的多路复用技术,很多平台都支持,poll是Linux平台下对select做的改进,而epoll可以说是目前Linux平台下性能最高的一种multiplexing技术,当然你得用好,尤其是LT和ET两种触发方式的使用。

下面简单总结了常见的服务器端使用的网络编程模型(包含线程模型)

先看看常见组件采用的模型(只看epoll):

nginx:master进程+多个worker进程,每个进程一个epoll eventloop
memcached: 主线程+多个worker线程,每个线程一个epoll eventloop
tornado:单线程,一个epoll eventloop
libevent:对于Linux平台封装了epoll
libev:对于Linux平台封装了epoll
boost.asio:对于Linux平台封装了epoll
muduo:对于Linux平台封装了epoll
nodejs的libuv:基于libev对epoll的封装

所以排除掉传统的单线程,多进程,多线程等模型,常见的高性能网络编程模型通常是one eventloop per thread与多线程的组合,或者为了处理耗时的任务再加上threadpool。通常为了更好地性能与并发,以master/worker的形式来配置进程线程模型。其实说到底各种高性能网络库或者框架还是在玩epoll+非阻塞,基础设施OS层面已经准备好了,最终看谁优化做得好。

值得注意的问题

  • 选择线程模型
    单线程下不用考虑同步等问题,one eventloop,相对容易很多
    多线程下要考虑多线程编程可能产生的各种竞争同步问题,协调各个thread里面的eventloop。
    多进程下要考虑各个eventloop thread的通信等问题
  • socket的读写
    这也是一大难点,尤其是epoll LT和ET方式下的读写,还有怎么优雅地处理各种错误。
  • 协议的设计
  • 使用文本还是二进制?json,xml,pb等等?
  • TCP/IP协议本身的深入理解
  • 日志
  • ……

应用层之外

前面都是基于应用层对于C10K这类问题的解决方案,在更高并发要求的环境下就得在内核态下做手脚了,如零拷贝等技术,直接越过内核协议栈,实现高速数据包的传递。相应的内核模块也早有实现。主要的技术点在于数据平面与控制平面分离、减少不必要的系统调用、用户态驱动uio/vfio等减少内存拷贝、内存池减少内存分配、减少缓存失效、batch syscall、用户态协议栈…相应的技术方案大多数是围绕这些点来做优化整合。比如OSDI ‘14上的best awarded paper-Arrakis、IX,再早的有pfring、netmap、intel DPDK、mTCP等等。

相关资源

  • 书籍:
    《UNIX环境高级编程》
    《UNIX网络编程》两卷
    《TCP/IP协议》三卷
    《Linux内核设计与实现》
    《深入理解Linux内核》
    《Linux多线程服务端编程》
  • 各种开源组件:
    nginx、memcached、beanstalkd、libevent、libev、muduo、boost.asio、ace、tornado、swoole等等
时间: 2024-09-09 03:53:14

网络编程的一些简单总结的相关文章

C# 网络编程之最简单浏览器实现

      最近学习C#网络编程的HTTP协议编程,HTTP即Hypertext Transfer Protocol的缩写,意为:超文本传输协议.其中与HTTP相关的知识主要有六个类的知识,分别是      (1).HttpWebRequest类:用于获取和操作HTTP请求:      (2).HttpWebResponse类:用于获取和操作HTTP应答:      (3).WebRequest类:用于获取和操作Web请求:      (4).WebResponse类:用于获取和操作Web应答:

C# 网络编程之网页简单下载实现

       这是根据<C#网络编程实例教程>中学到的知识实现的一个C#网页简单下载器,其中涉及到的知识主要是HTTP协议编程中相关类:HttpWebRequest类.HttpWebResponse类.WebRequest类.WebResponse类.Uri类.WebClient类.通过它们相应的方法实现,这里涉及到了4个新接触的知识点我想重点讲述:      (1).ComboBox控件:这是一个下拉列表的可编辑的文本框,右键该控件在显示的"编辑项"中添加网址,可见实例中

Lua下基本的网络编程示例

  这篇文章主要介绍了Lua下基本的网络编程示例,包括简单的服务器的搭建和相关web组件的介绍等,需要的朋友可以参考下 Lua是高度灵活的语言,它往往是在多个平台,包括Web应用程序中使用.成立2004年的Kepler社区提供Lua的Web组件开放源码. 虽然,也有使用Lua已经开发了其他的web框架,我们将主要集中在Kepler社区提供的组件. 应用程序和框架 Orbit 是一个lua的MVC Web框架,它是基于WSAPI. WSAPI是从Lua的Web应用程序抽象的Web主机服务器,是基于

C# 网络编程之网页自动登录 (一).使用WebBrower控件模仿登录

      最近学习C#网络编程中,想实现网页自动登录并提交GET/POST信息,再实现循环登录不断发送报文给服务器,服务器发送消息给客户端记录能登录的账户和密码,做到后面实现绕过验证码.动态抓取登录位置等,但由于资料很少.进度缓慢,下面这篇文章仅供大家交流阅读.      也许你可能看过一篇文章关于C#实现POST提交方式中三种提取网页HTML的方法:WebBrowser.WebClient.HttpWebRequest.我也看了很多人的博客,尤其是关于WebBrowser和HttpWebRe

C# 网络编程之通过豆瓣API获取书籍信息

这篇文章主要是讲述如何通过豆瓣API获取书籍的信息,起初看到这个内容我最初的想法是在"C# 网络编程之网页简单下载实现"中通过HttpWebResponse类下载源码,再通过正则表达式分析获取结点标签得到信息.但后来发现可以通过豆瓣API提供的编程接口实现.该文章仅是基础性C#网络编程文章,尝试测试了下豆瓣API,并没什么高深的内容.但希望对大家有所帮助,仅供学习.(警告:文章仅供参考,提供一种想法,否则访问多次-10次被403 forbidden莫怪.建议认证使用豆瓣API) 一.豆

iOS网络编程之三——NSURLConnection的简单使用

iOS网络编程之三--NSURLConnection的简单使用 一.引言     在iOS7后,NSURLSession基本代替了NSURLConnection进行网络开发,在iOS9后,NSURLConnection相关方法被完全的弃用,iOS系统有向下兼容的特性,尽管NSURLConnection已经被弃用,但在开发中,其方法依然可以被使用,并且如果需要兼容到很低版本的iOS系统,有时就必须使用NSURLConnection类了. 二.使用NSURLConnection进行同步请求     

java网络编程-Java写了个简单的网络编程程序,运行没有结果,求解谢谢!

问题描述 Java写了个简单的网络编程程序,运行没有结果,求解谢谢! import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import ja

iOS网络编程之二——NSURLSession的简单使用

iOS网络编程之二--NSURLSession的简单使用 一.NSURLSession简介     在iOS7之后,NSURLSession作为系统推荐使用的HTTP请求框架,在进行前台请求的情况下,NSURLSession与NSURLConnection并无太大差异,对于后台的请求,NSURLSession更加灵活的优势就将展现无遗.         1.NSURLSession集合的类型         NSURLSession类提供3中Session类型:         Default类

Java网络编程之简单的服务端客户端应用实例_java

本文实例讲述了Java网络编程之简单的服务端客户端应用.分享给大家供大家参考.具体如下: 在Java中,我们使用java.net.Socket及其相关类来完成有关网络的相关功能.Socket类非常简单易用,因为Java技术隐藏了建立网络连接和通过连接发送数据的复杂过程.下面所说的内容只适用于TCP协议. 一.连接到服务器 我们可以使用Socket类的构造函数来打开一个套接字,如 Socket sk = new Socket("210.0.235.14",13); 其中,210.0.23