以下部分内容参考文章
Socket本质上就是对TCP/IP协议组的封装。是应用层与传输层通信的中间层。从设计模式角度而言,Socket实际上是一组接口,。用户通过这些接口去组织数据,以符合指定的协议。Socket有三种类型,
- SOCK_STREAM 面向稳定通信,底层是TCP
- SOCK_DGRAM 无连接的通信,底层是UDP,需要上层协议来保证可靠性。
- SOCK_RAW 更加灵活的数据控制,可以指定IP头部。
常用Socket编程接口
- socket():创建socket
- bind():绑定socket到本地地址和端口,通常由服务端调用
- listen():TCP专用,开启监听模式
- accept():TCP专用,服务器等待客户端连接,一般是阻塞态
- connect():TCP专用,客户端主动连接服务器
- send():TCP专用,发送数据
- recv():TCP专用,接收数据
- sendto():UDP专用,发送数据到指定的IP地址和端口
- recvfrom():UDP专用,接收数据,返回数据远端的IP地址和端口
- closesocket():关闭socket
Socket通信流程
TCP流程
UDP流程
需要注意,TCP和UDP的端口互不干扰,所以说系统可以同时开启TCP80端口和UDP80端口
网络编程模型

- 同步阻塞迭代模型
1 | bind(srvfd); |
上述程序弊端:
- 如果没有客户端的连接请求,进程会阻塞在accept系统调用处,程序不能执行其他任何操作。(系统调用使得程序从用户态陷入内核态)
- 在与客户端建立好一条链路后,通过read系统调用从客户端接受数据,而客户端发送数据过来是不可控的。如果客户端迟迟不发生数据过来,则程序同样会阻塞在read调用,此时,如果另外的客户端来尝试连接时,都会失败。
- 同样的道理,write系统调用也会使得程序出现阻塞(例如:客户端接受数据异常缓慢,导致写缓冲区满,数据迟迟发送不出)。
- 多进程并发模型
多进程并发模型在同步阻塞迭代模型的基础上进行了一些改进,以避免是程序阻塞在read系统调用上。核心代码如下:
1 | bind(srvfd); |
- 多线程并发模型
在多进程并发模型中,每一个客户端连接开启fork一个进程,若客户端连接较大,则系统依然将不堪负重。通过多线程(或线程池)并发模型,可以在一定程度上改善这一问题。
在服务端的线程模型实现方式一般有三种:
- 按需生成(来一个连接生成一个线程)
- 线程池(预先生成很多线程)
- Leader follower(LF)
以第一种为例,其核心代码如下:
1 | void *thread_callback( void *args ) //线程回调函数 |
在这个模型中,服务端分为了两个线程,一是负责业务逻辑和流的读取。二是accept链接。
- IO多路复用
多进程模型和多线程(线程池)模型每个进程/线程只能处理一路IO,在服务器并发数较高的情况下,过多的进程/线程会使得服务器性能下降。而通过多路IO复用,能使得一个进程同时处理多路IO,提升服务器吞吐量。这是一种进程预先告知内核的能力,让内核发现进程指定的一个或多个IO条件就绪了,就通知进程。使得一个进程能在一连串的事件上等待。
IO复用的实现方式目前主要有select、poll和epoll。select和poll的原理基本相同:
- 注册待侦听的fd(这里的fd创建时最好使用非阻塞)
- 每次调用都去检查这些fd的状态,当有一个或者多个fd就绪的时候返回
- 返回结果中包括已就绪和未就绪的fd
相比select,poll解决了单个进程能够打开的文件描述符数量有限制这个问题:select受限于FD_SIZE的限制,如果修改则需要修改这个宏重新编译内核;而poll通过一个pollfd数组向内核传递需要关注的事件,避开了文件描述符数量限制。此外,select和poll共同具有的一个很大的缺点就是包含大量fd的数组被整体复制于用户态和内核态地址空间之间,开销会随着fd数量增多而线性增大。epoll的出现,解决了select、poll的缺点:
基于事件驱动的方式,避免了每次都要把所有fd都扫描一遍。
epoll_wait只返回就绪的fd。
epoll使用nmap内存映射技术避免了内存复制的开销。
epoll的fd数量上限是操作系统的最大文件句柄数目,这个数目一般和内存有关,通常远大于1024。
select:支持注册 FD_SETSIZE(1024) 个 socket。
poll: poll 作为 select 的替代者,最大的区别就是,poll 不再限制 socket 数量。
epoll:epoll 能直接返回具体的准备好的通道,时间复杂度 O(1)。
C在win平台创建socket的实例
1 | WSADATA wsaData; |