
Unix网络编程
文章平均质量分 85
yuanhaitaozz
啊啊啊啊啊啊啊啊
展开
-
Nginx基础. 防止惊群与子进程之间的负载均衡
作为服务器子进程, 每个worker进程都需要处理大量网络事件. 而网络事件的处理来源于对监听端口新连接的建立.当有多个worker进程同时监听同一个(或多个)端口时, 建立连接就没那么简单了.Nginx出于充分发挥多核CPU性能的考虑, 则使用了多个worker子进程的设计. 这样多个子进程在accept建立连接时候就会有争抢, 产生"惊群"问题. 有的系统可能在内核就解决了这个问题,原创 2015-09-25 19:46:49 · 1352 阅读 · 0 评论 -
网络编程基础函数
开头复习一下一个标志: O_APPEND 关于 O_APPEND 当多核、众核CPU成为线上服务器的主流时,为了充分利用系统的多核处理能力,最常见的思路是将原先单进程单线程的程序改造成多进程或多线程的程序。 对于多进程或多线程的程序,一种常见的需求就是并发写日志的需求。为了解决这个需求,最容易想到的思路是利用linux进程或线程同步机制保证并发写的时候日志不会相互原创 2015-03-22 16:46:09 · 512 阅读 · 0 评论 -
Nginx基础. Nginx配置解析
之前给出了配置简单模块的例子, 现在来仔细分析一下配置文件中的 http, server, location这三个部分.在配置文件中, 在http块下可以有多个server块, 在servre块下可以有多个location块, 在location块下仍然可以有location块.同一个配置项可以同时出现在多个http块, server块, 或是location块内.既然如此, 就远原创 2015-09-08 22:48:19 · 1640 阅读 · 0 评论 -
Nginx---基础知识. Nginx特色
命令行控制:1. 默认启动方式: /usr/local/nginx/sbin/nginx这里的路径是 ./configure 的默认路径, 如果有指定新的路径, 则在新路径的相应文档下. 默认启动时, 会读取默认路径下的默认配置文件 /usr/local/nginx/conf/nginx.conf 2. 另一种指定配置文件的启动方式:使用 –c 参数指定原创 2015-08-17 15:22:41 · 703 阅读 · 1 评论 -
Nginx基础. Nginx基本哈希表
根据以往的学习经验, 比如STL中的哈希表, 利用开链法, vector+list作为容器, 当hashtable中的元素总数超过一定数量时, 选择扩充vector.再比如libevent中的哈希表, 与STL中的哈希表类似, 但比较复杂, 每个bucket中都可能有一个链表,每个链表元素中也可能存在一个链表. 但理解起来都并不复杂.现在看的Nginx中的哈希表, 则与上面谈到的哈希有很明原创 2015-08-31 22:33:42 · 3060 阅读 · 1 评论 -
Nginx基础. Nginx数组与链表
ngx_array_t实现文件: ./src/core/ngx_array.h ./src/core/ngx_array.c1. 数据结构定义typedef struct { void *elts; //数组数据区起始位置 ngx_uint_t nelts; //当前存放元素个数 size_t原创 2015-08-29 19:43:42 · 1122 阅读 · 0 评论 -
Nginx基础知识. Nginx内存池分析
Nginx内存池1. 内存池结构定义struct ngx_pool_s { ngx_pool_data_t d; //内存池的数据部分 size_t max; //内存池中, 每个内存块的最大数据容纳量 ngx_pool_t *current;原创 2015-08-29 19:38:47 · 448 阅读 · 0 评论 -
关于System V 信号量
System V的信号量与Posix的信号量略有差异在原有的二值信号量与计数信号量基础上, System V信号量多了一种计数信号量集: 一个或多个信号量(构成的集合), 其中每个都是计数信号量. 每个集合的信号量数存在一个限制.所以, 一般我们谈论Posix信号量, 指的是单个信号量; System V信号量则表示多个信号量集操作函数:int semget(原创 2015-08-02 20:43:20 · 559 阅读 · 0 评论 -
关于Posix的信号量
基本介绍信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语,我们将会讨论3钟类型的信号量 1、POSIX有名信号量, 可用于进程间或线程间同步 2、POSIX基于内存的信号量:存放在共享内存区中,可用于进程间或线程间同步 3、System V信号量:在内核中维护,可用于进程间或线程间同步信号量可以被指定为二值信号量, 往往用于互斥的目的原创 2015-08-02 20:36:57 · 631 阅读 · 0 评论 -
System V IPC 初识以及简单介绍
这里将会讨论对于System V IPC的初步认识以下三种类型的IPC合称为System V IPC: System V 消息队列 System V 信号量 System V 共享内存区key_t键 和 ftok函数 以上谈到的三种IPC都使用key_t作为他们的名字. key_t在头文件中被定义为一个整数, 通常至少为32位 函数原创 2015-07-21 17:22:25 · 2764 阅读 · 0 评论 -
简单的心搏函数
心搏函数 可以发现对端主机或到对端的通信路径的过早失效在考虑使用心搏函数前, 可能会先考虑到TCP自带的保活特性, 即SO_KEEPALIVE套接字选项. 然而TCP默认需要在闲置2小时后才发送一个保持存活探测段. 意识到如此后, 接下来可能会想着能不能修改这个参数, 使TCP更早的检测失效. 答案是可行的, 大多系统都支持修改此参数. 但是这些参数通常是按照内核而不是按照每个套原创 2015-08-11 21:56:03 · 738 阅读 · 0 评论 -
套接字选项SO_LINGER, SO_KEEPALIVE等
int getsockopt(int sockfd, int level, intoptname, void *optval, socklen_t *optlen);int setsockopt(int sockfd, int level, intoptname, const void *optval, socklen_t optlen);//获取与设置套接字选项的函数通用套接字选项:原创 2015-04-21 17:23:36 · 2857 阅读 · 0 评论 -
Nginx基础. 开发HTTP过滤模块
1. HTTP过滤模块的地位, 作用与一般的HTTP模块是不同的, 一个请求可以被任意个HTTP过滤模块处理. 它所做的工作是对发送给用户的HTTP响应包做一些加工.相较于"普通的HTTP模块更倾向于完成请求的核心功能, 比如static模块负责静态文件的处", HTTP过滤模块则处理一些附加的功能, 比如gzip过滤模块可以把发送给客户的静态文件进行压缩后处理再发出去; image_fi原创 2015-09-08 23:06:39 · 1587 阅读 · 0 评论 -
关于Posix共享内存
Posix提供了两种在无亲缘关系的进程间共享内存区的方法: 1. 内存映射文件 由open函数打开, 由mmap函数把得到的描述符映射到当前进程的地址空间的一个文件 2. 共享内存区对象 由shm_open打开一个Posix IPC名字, mmap将得到的描述符映射到当前进程的地址空间 两者的差距在于获取描述符的手段原创 2015-08-03 17:12:26 · 510 阅读 · 0 评论 -
Nginx基础知识. Nginx模块开发
Nginx模块开发初识 下面将开发一个简单的HTTP模块作为线索进行讲解.Part1. 模块需要使用的信息存储结构关于ngx_module_t既然要进行模块开发, 那么就必须会使用到存储模块的数据结构, 下面先看看这个结构体//因为是初识, 所以结构体的一些变量暂时不管typedef struct ngx_module_s ngx_module_t;struc原创 2015-08-25 11:04:01 · 841 阅读 · 0 评论 -
Nginx基础. Nginx通配散列表
之前学习过Nginx中的普通散列表, 关于其初始化以及整体的构造有了大致的了解.接下来就是在普通散列表的基础上, 分析更复杂的散列表构造. 因为Nginx作为一个Web服务器, 它的各种散列表中的关键字多以字符串为主, 特别是URI域名, 比如 www.ben.com.既然是这样, 那么Nginx就需要去支持带有通配符的主机域名, 即带"*"的域名, 包括前置通配符, 如 *.test原创 2015-09-12 11:21:53 · 2811 阅读 · 1 评论 -
Nginx基础. Nginx基本哈希构成
回顾.下面这个函数是基本散列表的初始化函数. 在http://blog.youkuaiyun.com/u012062760/article/details/48140449中也介绍的比较详细了.ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts);具体的函数内容这里不再谈了原创 2015-09-12 11:21:27 · 504 阅读 · 0 评论 -
Nginx基础. eventfd, 异步IO 与epoll的相互协作
关于eventfd.对于eventfd, 这里只是简单的讲它的功能. 看manpage就足够了, 其中的例子也很容易看懂eventfd函数可以创建一个efd描述符, 该描述符在内核中维护着一个计数器counter. 在调用eventfd时, 可以传入参数指定内核中维护着的计数器的值.如果这样调用: int efd = eventfd(0, 0);那么计数器值为0.原创 2015-09-25 19:53:38 · 4235 阅读 · 5 评论 -
Nginx基础. epoll事件驱动模块
关于epoll事件驱动模块, 这里不做过多分析. 主要着眼于事件添加和事件处理上.static ngx_int_tngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags){ int op; uint32_t events,原创 2015-09-25 19:38:27 · 1081 阅读 · 0 评论 -
Nginx基础. 认识Nginx事件模块 (二)
对于事件模块, 定义此模块解析配置项的工作交给了ngx_events_module, 对于事件驱动机制, 更多的则是在ngx_event_core_module中进行的.相比于属于核心模块的ngx_events_module, ngx_event_core_module则属于事件模块.在ngx_modules.c文件中, ngx_event_core_module模块被放在了所有事件模块的原创 2015-09-25 19:31:40 · 479 阅读 · 0 评论 -
Ngixn基础. 认识Nginx事件模块(一)
对于Nginx的整体框架, 尚且只能了解个大概, 并不能弄清除整个流程. 索性先放着, 先了解其他组件.事件处理框架所要解决的问题是如何收集, 管理, 分发事件. 且事件类型主要为网络事件和定时器事件.既然需要支持跨平台, 那么就肯定要封装不同平台的事件驱动机制. 当然, 我只能看懂select, poll, epoll这几个... 那么Nginx是如何选择的呢? 1 . 之前在原创 2015-09-25 19:30:01 · 2679 阅读 · 0 评论 -
同一个父进程的多个子进程之间的通信
对于父子进程之间的通信, 或者是没有亲缘关系的进程之间的通信, 之前都有过多多少少的了解, 就不作说明了.这里想要讨论的是多个子进程之间的通信.以前若是有多个子进程之间通信的需要, 那么我可能会选择使用共享内存? 使用消息队列? 或者使用一系列进程间通信机制但这些同样适用于没有亲缘关系的进程之间的通信. 这样做似乎没有必要.这里将要实现的子进程之间的通信, 使用了两个技术:原创 2015-09-25 19:34:20 · 6672 阅读 · 1 评论 -
Nginx基础. Nginx模块上下文
这里要提到的上下文是针对HTTP请求的, 每个HTTP请求对应于每一个HTTP模块都可以有一个独立的上下文结构体.(可以看出, 并不是一个HTTP请求的上下文由所有HTTP模块共享)每个请求对于每个模块的上下文结构体一般是在刚开始处理请求时在内存池分配它. 之后经过epoll, HTTP框架再次调用到HTTP模块的处理方法时, 这个HTTP模块可以由请求的上下文结构中获取信息. 在请求结束后,原创 2015-09-08 22:54:30 · 3115 阅读 · 0 评论 -
使UDP服务器尽可能可靠
如果想要让请求应答式程序使用UDP, 那么必须在客户程序中增加以下两个特性: 1. 超时和重传 2. 供客户验证一个应答是否匹配相应的请求首先, 为了防止数据包的丢失: 增加序列号比较简单. 客户为每个请求冠以一个序列号, 服务器必须在给客户的响应中echo这个序列号, 这样客户端就能验证某个给定的应答是否匹配早先发出的请求其次, 为了解决数据包超时:原创 2015-08-11 21:49:51 · 505 阅读 · 0 评论 -
Nginx基础知识. Nginx网络属性
Nginx基础概念先是对connection的概念介绍 nginx中的connection就是对tcp连接的封装, 其中包括连接的socket, 读事件, 写事件. 所以, 利用此connection, 就可以与任何后端服务打交道. nginx是如何处理一个连接的呢? 首先, nginx在启动时, 解析配置文件, 得到需要监听的端口与ip地址, 然后在n原创 2015-08-22 14:46:45 · 1209 阅读 · 0 评论 -
关于System V 消息队列介绍
关于SystemV消息队列操作函数:int msgctl(int msqid, int cmd, struct msqid_ds*buf);操作选项: IPC_RMID 从系统中删除mqisd指定的消息队列.仍在队列上的消息都丢弃 IPC_SET 给所指定的消息队列设置其mqsid_ds结构的几个成员: uid, gid, mode,msq_qbytes原创 2015-07-26 19:32:33 · 1382 阅读 · 0 评论 -
IP选项初识
IPv4允许在20字节首部固定部分之后跟以最多40个字节的选项,最常用的是源路径选项。这些选项的访问途径是存取IP_OPTIONS套接字选项。IPv6允许在固定长度的40字节IPv6首部和传输层(ICMPv6、TCP或UDP)首部之间出现扩展首部。 不同于IPv4的是,IPv6的扩展首部的访问途径是函数接口。IPv4选项: 根据下图IPv4首部格式,发现IPv4选项字段跟在2原创 2015-04-26 20:59:08 · 2913 阅读 · 0 评论 -
第二十六章 线程
之前提到的并发服务器,父进程accept一个连接,fork一个子进程,该子进程处理与该连接对端的客户之间的通信。但是fork调用却存在一些问题: 1、fork是昂贵的。即使如今使用了"写时复制(copy on write)"技术,用以避免在子进程切实需要自己的副本之前把父进程的数据空间复制到子进程,但仍然是昂贵的 2、fork返回之后父子进程之间的信息传递需要进程间通信(I原创 2015-04-08 19:30:27 · 424 阅读 · 0 评论 -
服务器设计范式(二)
4、TCP预先派生子进程服务器程序,accept使用文件上锁保护为什么我们要给accept上锁呢?因为不同的系统实现。 书中提到,没加锁的程序在4.4BSD上运行,实现允许多个进程在引用同一套接字的描述符上调用accept,然而这种做法也仅仅适用于在内核中实现的源自伯里克内核。相反,System V不支持这么做。在某些不支持的系统上运行不加锁的程服务器时,某个子进程accept会返回原创 2015-04-20 17:02:26 · 476 阅读 · 0 评论 -
服务器设计范式
我们将在本章探究并发服务器程序设计的两类变体1、预先派生子进程,让服务器在启动阶段调用fork创建一个子进程池,每个客户请求由当前可用的子进程池中的某个(闲置)子进程处理2、预先创建线程,让服务器在启动阶段创建一个线程池,每个客户由当前可用线程池中的某个(闲置)线程处理我们将针对同一客户端程序运行这些服务器以便相互比较客户端程序代码如下:#include "unp.原创 2015-04-16 18:39:16 · 631 阅读 · 0 评论 -
第十六章非阻塞connect实例 与 非阻塞accept
非阻塞connect: Web客户程序 客户先建立一个与某个Web服务器的HTTP连接,再获取一个主页(homepage)。该主页往往含有多个对于其他网页的引用,客户可以使用非阻塞connect同时获取多个网页,以此取代每次只获取一个网页的串行获取手段。 在处理web客户时,第一个连接独立执行,来自该连接的数据含有多个引用,随后用于访问这些引用的多个连接则并行执行 这原创 2015-04-07 16:23:00 · 590 阅读 · 0 评论 -
第十六章 非阻塞connect初识
非阻塞connect 当在一个非阻塞的TCP套接字上调用connect时,connect将立即返回一个EINPROGRESS错误,不过已经发起的三路握手将继续进行。我们接着使用select检测这个连接或成功或失败的已建立条件。 非阻塞的connect有三个用途: 1、我们可以把三路握手叠加在其他处理上。完成一个connect要花一个RTT时间,而RTT不稳定,这段时间原创 2015-04-07 16:17:24 · 370 阅读 · 0 评论 -
Unix域套接字
Unxi域套接字并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API就是在不同主机上执行客户/服务器通信所用的API。可以视为IPC方法之一。UNix域提供两类套接字:字节流套接字(类似TCP),数据报套接字(类似UDP)使用Unix域套接字有以下三个理由: 1、Unix域套接字往往比通信两端位于同一主机的TCP套接字快出一倍。X Window原创 2015-04-19 18:05:56 · 2616 阅读 · 0 评论 -
IPv4 和 IPv6的互操作性
IPv4客户与IPv6服务器通信步骤如下: 1、IPv6服务器启动后创建一个IPv6监听套接字,我们假定服务器把通配地址绑定到该套接字 2、IPv4客户调用gethostbyname找到服务器的A记录(IPv4地址)。服务主机既有一个A记录,也有一个AAAA记录(IPv6地址),因为它同时支持IPv6和IPv4,不过客户只需要A记录 3、客户调用connect,导原创 2015-04-02 16:55:25 · 3464 阅读 · 0 评论 -
第十六章 非阻塞I/O
第十六章、非阻塞式I/O什么是阻塞socket和非阻塞socket?两者的具体区别是什么? 读操作 对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲区中的数据大于期望读取的字节数时,读取期望读取的字节数原创 2015-04-01 15:58:17 · 466 阅读 · 0 评论 -
UDP编程初识
复习:TCP 每个TCP套接字都有一个发送区,我们可以使用SO_SNDBUF来更改缓冲区的大小,当进程调用write时,内核从该应用进程的缓冲区中复制所有数据到套接字的缓冲区。如果该套接字的发送缓冲区容不下该应用进程的所有数据(或是应用进程的缓冲区大于套接字的发送缓冲区,或是套接字的发送缓冲区已有其他数据),该应用进程将被投入睡眠(这里的套接字是阻塞的),内核将不从write系统调用原创 2015-03-24 19:54:43 · 472 阅读 · 0 评论 -
epoll简介
内核事件表1、epoll使用一组函数来完成任务,而不是单个函数2、epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中,从而无需像select和poll一样每次调用都要重复传入文件描述符集或是事件集。3、但是epoll需要使用一个额外的文件描述符,来唯一标志内核中的这个事件表 使用 int epoll_create(int size) 来创建,原创 2015-05-08 14:57:17 · 514 阅读 · 0 评论 -
线程特定数据 Thread Specified Data
1、为什么需要用到线程特定数据? 因为在单个线程的程序中,当我们调用同一个函数多次,若其中有静态、全局变量,该变量会随着每一次调用发生变化。 然而在多线程中,当多个线程同时调用同一个函数,若该函数没有全局、静态变量,那么不会引发错误;否则,我们就需要用到锁来解决问题。 这里提供的线程特定数据,是使线程函数变为线程安全的一个常用技巧2、每一个系统支持的线程特定元原创 2015-04-08 19:33:01 · 584 阅读 · 0 评论 -
关于Posix的消息队列
消息队列可以认为是一个消息链表. 有足够写权限的线程可以往队列中放置消息, 有足够读权限的线程可以从队列中取走消息在某个进程往一个队列写入消息前, 并不需要另外某个进程在该队列上等待消息的到达. 这跟管道和FIFO是相反的, 因为对于管道,FIFO来说, 除非读出者已经存在, 光有写入者是没有意义的一个进程在往某消息队列写入消息后, 终止进程. 另一个进程某时刻读出原创 2015-07-26 18:12:22 · 3145 阅读 · 0 评论 -
管道与FIFO属性了解
关于半双工管道pipeint pipe(int pipefd[2]);函数返回两个文件描述符: pipefd[0]和pipefd[1]. 前者打来来读, 后者打开来写管道的典型用途是为两个不同进程(父进程与子进程)提供进程间的通信手段当我们需要(假设现在提供的pipe是半双工的)双向数据交流的时候,我们必须创建两个管道: 创建管道1 (fd1[0]和fd1[1])和管道2原创 2015-07-26 18:08:14 · 729 阅读 · 0 评论