哲学socket 开发 – 那一个年用过的基础 API

冯芝生先生的《中国医学简史》是冯老在美利哥助教中国法学史时的讲稿整理而成,系列较庞大,内容丰裕,语言流畅,书中融入了重重对我本人对华夏历史学的敞亮,是一本草拾遗典的炎黄管理学入门书籍。别的,书中的中国教育学的灵气及精髓以及各家的看好,很难随便就读得读全,更不用说所有明白并内化为协调的学问了,每一片段都急需细细研读与沉思,由此笔者依照本人的翻阅和驾驭,首要从中华经济学的表征和旺盛,以及中国法学与别国经济学的异议等方面来写自身的一些回味及感想。
普罗马自达都耳熟能详孔丘、老子、孟轲等人选,都精通他们是考虑家,都以有大学问之人,很少有人有关于他们的军事学的定义,在大家从未接触到天国医学史,我们尚不知道中国历史学时,这时大家都说大家有丰硕博大的中原考虑、中国智慧,接触了西方艺术学后大家才发现,原来我们泱泱大国也有相似于西方法学的东西,之所以要用相似,笔者个人的理念是,中国的“理学”和西方的医学在含义上是不平等的,但是思考在某些圈子是兼具相似性的,那话不对等说中国从不军事学,而是说我们要掌握中西教育学那几个内涵和情节是不一致的,即使都用了医学那几个词来称呼。我们都知情在西方很已经有专门从事艺术学啄磨的人,而且很快发展成一门专业,而且是宏观的业内,后来正确等才逐步从文学里分别了出去。
只是在华夏我们是根本没有“教育学”这些知识科目的,大家古板的唐宋华夏有啥样吗?大家有经学、史学,大家许多思想、文化、艺术,只不过是我们的思辨种类太庞大精深,包括太多,管理学那几个词也是舶来的,并非我们发明创立。而中华的经济学也是从茫茫的神州考虑史中抽出来的,阅读时咱们会发觉,在几千年前,大家的祖辈翻译家和西方的翻译家们竟在有关宇宙、关于万物、关于人生有这几个的相似之处,极度的妙趣横生。同时很有多如牛毛的例外,那么些接下即将说到。
先是,中国的管理学其实在神州知识中占了很重点的地位,根据冯芝生先生的话说,完全可以和教派的身价相比较,不仅是大家,几百年甚至几千年前的文化人,打小就学四书五经,背诵三字经千字文,伊始的两句:“人之初,性本善”,不就是亚圣的医学观念吗。不仅是我们,西方人也意识了笔者们这一表征,他们看来法家生活渗透到了华夏人的生活,觉得说墨家的思想不就是儒教吗,严峻的来说,我们的儒家学说在好几效率上有宗教的风味,不过它与宗教依然出入。就如说道家是艺术学学派,东正教是宗教,佛学是农学,而道教是宗教,他们前后两边的力主相差甚大。道家主张叫人适合自然,而东正教教人寻找不死的方术;可是教育学、宗教是多义词,不相同的人心中有差其他思想意识。
附带,说到中华经济学我们先是想到的就是“出世”和“入世”,出世的艺术学讲究脱离尘世、脱离生死,达到最终的摆脱。而入世的艺术学爱慕社会中的人伦和事务,它侧重的是道义价值。Fung先生说:“从入世文学的观点看,出世的理学太理想主义、不实用、消沉。从降生工学的视角看,入世的农学太现实主义、太肤浅了”。
在炎黄文学里,主要的派系就是道家和道家,法家学说是社会团体的法学,也是有关经常生活的法学,法家强调人的社会权利感,可是法家强调人的里边的当然,中国管理学的那二种倾向,就一定于是上天的古典主义和浪漫主义,大家在读青莲居士和杜拾遗的诗时,就能肯定感觉到法家与道家的差异。
《庄周》中说:“法家游方之内,法家游方之外”,这一个方就指的是社会,这三种相持在某一方面提供了一个平衡。
许多个人说中国的文学是入世的文学,那一点无法说全对也不可以说全错,确实我们的教育学无论是哪一家都平昔或直接的讲到政治和道德。从表面上看,中国理学较爱慕社会国家、人伦日用,而不是宇宙万物、上帝天堂。出世和入世是周旋的,在书中冯芝生认为中国法学的精神是谋求出世和入世这些反命题的联结,在中原工学里认为能落成那样的叫“内圣外王”,内圣是修养的完结说,外王是社会的法力说。在历史上也有过那样的思潮出现,儒家像让本人类似一点道家,墨家想让祥和好像一点法家,赋予它们新的意义,因而有了魏晋南北朝时期的“新道家”和“新法家”,如宋明时代的程朱历史学和陆王心学,以及近代的新儒学的表示人物像熊继智、金龙荪、梁寿铭、牟宗三等,大家纯熟。
中国历史学的另一特天性是言语难题,何出此言?中国的思想家表明思想的办法很相当,言杂谈字十分长很粗略,言论、小说没有外部上的联络,他们也不是规范的管理学作品,很多文字的记录或是书籍的完整收集也不是在一个定点的一时,也从不文学家这几个事情,所以我们明白起来就一定的有难度了,先哲们固然有一些演绎和论证,但都是相比较少的,而且也是不够明晰的,那是因为中国的思想家们爱用名言隽语、比喻例证的花样来公布自个儿的看法。冯老在书中说:“名言一定很简短,比喻例证一定非亲非故系”。到此处大家又取得了炎黄法学的另一个特点——明晰不足、暗示有余。正是因为明细不足。所以才暗示有余,用后世补充前者,以促成某种平衡。富于暗示、不清楚不仅是华夏文学的特色,也在华夏文化的大队人马地点有展示,大家的诗句、绘画、礼仪都浮现了内敛含蓄、暗示委婉的特点,所以聪明的人就会去寻觅醉翁之意不在酒,可是儒道的议论就算简易,可是却Paul万象,余音绕梁,其中的灵气永远都研商不尽。
中原管理学的另一个特征就是知识论一贯不曾升高起来,Fung先生在书中说:“认识论为题的指出,唯有在强调差异主观和合理性的时候才有,在审美两次三番体中从未这么的区分,在审美三番五次体中认识者和被认识者是一个完好无损”。正是出于那种全部性的观念,使得把进度和结果就是了一个总体,而来认识论就是发生于那么些历程是什么样发生结果的,因此认识论在那种全部下并未提喜气洋洋起。
那是什么使中国教育学不一样与天堂的医学,具有深厚的神州特点吗?
首先是神州的地理背景,《论语》里说:“智者黄石、仁者乐水”,中国是大陆国家,在南齐人的眼里大家没有世界的概念,我们一些只是“天下”“江山“
”四海“的定义,所以大家很自然的去思想社会与个体与国家,而很少去考虑天地宇宙。
附带是礼仪之邦的经济背景,中国是大陆国家,所以以农业为生,而西方则以商业为生,所以在咱们的思索当中就有了故事情节之分,不一样故事情节的理由是,农业关系到了生产,而买卖只提到到交流,在交流此前必须是先要有生育才行,所以农业成了中华最根本的生产方式。其余还跟农商的生活方法有涉嫌,“农”朴实天真,一幅土地,他们的财产一定单一,不便于随便迁移,由此卓殊的平安;“商”心境多财产不难转运,因而不安宁。
农的生活方法和见闻不仅限制着中华医学的故事情节还限定着中国法学的方法论,更影响了中华国学家思维方式,就如对于庄稼和田地等同,把对于事物直接的领会作为了经济学的落脚点,保养全部,忽略了认识进程。因而也简单解释工业就或然说科学为何向来不在华夏向上起来,农的活着方法是契合自然,他们谴责人为,而工业是行使本来、改造自然,二者相悖自然工业不可以前行了。
希腊共和国(The Republic of Greece)人在世在深海国家,他们凭借商业,所以城市连忙提升了起来,然后随之而来的是城邦政治,而中国的社会制度是家邦制度,大家以家庭为单位关键格局。海洋国家的人就好像孔仲尼说的是“智者”,他们聪明、精细,而中华人就是“仁者”。
读完此书,对中华军事学的掌握尚处在管窥之见的阶段,自个儿的感想也比较散乱,大约的留给了几点的回想关于中华教育学及海外理学:大陆国家与海洋国家、商业与农业、富于暗示明晰不足、出世与入世、理想与具体、城邦与家邦、仁者与智者等词汇,那是初读Yulan先生的《中国理学简史》的少数感想。此外,还纪念了冯老先生在书中说到的一句话:“经济学时使人看做人而改为人,而不是变成某种人”。


2017年12月28日

前言 - 思考依旧


  socket 写过一点点,  总觉得很别扭. 例如 read, recv, recvfrom
那些为何这么奇葩. 那是 linux 的统筹吗.

那种强糅合的 read 代码, '带坏'了不怎么人. 想起很久之前看过的
<<UNIX痛恨者手册>>, 外加上常写点跨平台

库. 不得不考虑设计, 发现 

  1) winds 对于 socket 设计比 linux POSIX 设计了然越发自身一丢丢

  2) linux 质量比 winds 好. (开源管理学 对冲 精英文化)

  3) 应用层是个不完备的域, 不要一条胡同走不彻底

(备注 : 有一段日子特别讨厌 winds, 及其喜欢羡慕 unix,
但是随着成长认识有了很大转变, 痛恨没钱没时间)


正文 - 来点评释


1. 即便得以不妨多写点跨平台, 线程安全的代码

  不妨举个烂大街的例证, 我们经常在处理时间的时候一贯用  gettimeofday

#include <sys/time.h>int gettimeofday(struct timeval * tv, struct timezone * tz);The functions gettimeofday() can get and set the time as well as a timezone. The tv argument is a struct timeval (as specified in <sys/time.h>): struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };and gives the number of seconds and microseconds since the Epoch (see time(2)). The tz argument is a struct timezone: struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of DST correction */ };If either tv or tz is NULL, the corresponding structure is not set or returned. (However, compilation warnings will result if tv is NULL.)The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.

只是简单的取得当前时间秒数和毫秒, 附赠一个时区新闻. 那个函数一眼看千古,
设计的不漂亮.

一经指望您的代码可以在 winds 上边也小跑, 恐怕要求一个移植版本 

#ifdef _MSC_VER#include <winsock2.h>//// gettimeofday - Linux sys/time.h 中得到微秒的一种实现// tv : 返回结果包含秒数和微秒数// tz : 包含的时区,在winds上这个变量没有用不返回// return : 默认返回0//inline intgettimeofday(struct timeval * tv, void * tz) { struct tm st; SYSTEMTIME wtm; GetLocalTime(&wtm); st.tm_year = wtm.wYear - 1900; st.tm_mon = wtm.wMonth - 1; // winds的计数更好些 st.tm_mday = wtm.wDay; st.tm_hour = wtm.wHour; st.tm_min = wtm.wMinute; st.tm_sec = wtm.wSecond; st.tm_isdst = -1; // 不考虑夏令时 tv->tv_sec = (long)mktime(&st); // 32位使用数据强转 tv->tv_usec = wtm.wMilliseconds * 1000; // 毫秒转成微秒 return 0;}#endif

一致你的工作量已经起来了. 不管高不高效. 总是个下策. 那里有个更好的主张,
利用  timespec_get 

#include <time.h>/* Set TS to calendar time based in time base BASE. */inttimespec_get (struct timespec *ts, int base){ switch (base) { case TIME_UTC: if (__clock_gettime (CLOCK_REALTIME, ts) < 0) return 0; break; default: return 0; } return base;}

C11 标准提供的拿到秒和毫秒的时刻函数, CL 和 GCC clang 都提供了帮助.
上边是glibc中一个贯彻, 是或不是很 low.

扯一点

  1.1 写代码应该有很强的目标, 非特殊领域应该弱化针对性

  1.2 上层应用, 应该尊敬向着标准靠拢, 其次是操作系统, 再到编译器

对于CL 实现了 timespec_get, 应该最首要目标是为着 C++11基础性格帮助,
还有 clang 的落成.


2. 你是不是和本人同样曾经因为 WSAStartup 大骂微软SB

  写 socket winds 一定会有上边三部曲, 可能两部曲. 

// 1. CL 编译器 设置引入库 ws2_32.lib 引入宏 _WINSOCK_DEPRECATED_NO_WARNINGS// 2. 加载 socket dll WSADATA wsad; WSAStartup(WINSOCK_VERSION, &wsad);// 3. 卸载 WSACleanup

当时想, linux 为什么木有上面这么无意义的操作.  其实其中有个故事,
当初微软不足了一代, 不能和unix socket互连.

前面来回扯, 其余众多巨擎给其 Winsock 升级, dll 版本变化厉害.
所以有了上面抛给用户层加载绑定dll版本的操作.

那就是说再linux 上边的确不必要吗. 其实也要求, 只是在运转 _start
时候辅助我们做了. 所以那点下边完全可以那样

封装 

//// socket_init - 单例启动socket库的初始化方法// inline void socket_init(void) {#ifdef _MSC_VER WSADATA wsad; WSAStartup(WINSOCK_VERSION, &wsad);#elif __GUNC__ signal(SIGPIPE, SIG_IGN) #endif}

3. 还记得 read, recv, recvfrom 吗 ?

  还处于整个皆文件决定的恐怖中吗.
完结那种思路无外乎注册和switch工厂分支. 那就代表 read 是个杂糅

体. 在我们只是拔取 socket fd 读取的时候 最后 read -> recv
这么些函数调用, 即 recv(fd, buf, sz, 0). 对于后者 

ssize_t__libc_recv (int fd, void *buf, size_t len, int flags){#ifdef __ASSUME_RECV_SYSCALL return SYSCALL_CANCEL (recv, fd, buf, len, flags);#elif defined __ASSUME_RECVFROM_SYSCALL return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, NULL, NULL);#else return SOCKETCALL_CANCEL (recv, fd, buf, len, flags);#endif}

可以注解 recv 和  recvfrom 完成层面有过纠缠. 但是和 read 上层没有耦合.
所以对于唯有 TCP socket 最好的

做法仍旧 recv 走起. 

 #include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags); ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

里头对于 recv flags 有上边多少个多平台都协助的宏 

#define MSG_OOB 0x1 /* process out-of-band data */#define MSG_PEEK 0x2 /* peek at incoming message */#define MSG_DONTROUTE 0x4 /* send without using routing tables */#if(_WIN32_WINNT >= 0x0502)#define MSG_WAITALL 0x8 /* do not complete until packet is completely filled */#endif //(_WIN32_WINNT >= 0x0502)

骨子里开发中, MSG_OOB 带外数据, 除非学习. 否则无意义. MSG_PEEK 在从前的
\r\n 切分流协议的时候还用.

当今着力都尚未场景. MSG_WAITALL 可以品尝一下代表很久在此在此之前的 for read.
可以有轻微升高质量. 

recv(fd, buf, len, 0) or recv(fd, buf, len, MSG_WAITALL)
用在您的常说的'高品质'服务器中而不是大杂烩 read.


4. 是否为 listen, accept 好奇过 !

  首先从 listen 和 accept 一对好cp说起. 其实大体进度无外乎 listen
-> connect -> accept .  这里只是从用法

而言首先看 listen 部分 

/* * Perform a listen. Basically, we allow the protocol to do anything * necessary for a listen, and if that works, we mark the socket as * ready for listening. */SYSCALL_DEFINE2(listen, int, fd, int, backlog){ struct socket *sock; int err, fput_needed; int somaxconn; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock) { somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn; if ((unsigned int)backlog > somaxconn) backlog = somaxconn; err = security_socket_listen(sock, backlog); if (!err) err = sock->ops->listen(sock, backlog); fput_light(sock->file, fput_needed); } return err;}

这段 listen 代码写得真赏心悦目. 作者从中看出来, 内核的思路仍然注册.  对于
backlog 存在一个最大值.

之所以对于高品质服务器 listen 正确的写法推荐 

listen(fd, SOMAXCONN)

把 listen创造的监听和链接成功队列大小交给操作系统的木本配置. 

对此 accept 原本想讲一讲 accept4 + SOCK_NONBLOCK 下落 socket 开发流程.
可是一想起 unix or winds

应该不扶助算了. 还是老实 accept + O_NONBLOCK. 

SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen){ return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);}

黑马发现到优化就是人命枯竭, 打击痛点才是王道.


5. 你为 select 困扰过呢, 去它的 poll 

  其实想想 select 那种函数设计的真正很奇葩. select -> poll ->
epoll 从床上到床下经历过多少夜晚. 

重点是 winds 和 linux 对于 select 完全是三个函数, 恰巧名字一样.
经过下边一个不好的材质精通

一个的确的客户端非阻塞的
connect

select 开发中的用法. 为啥讲 select, 因为便宜 winds 移植调试 !!
iocp很吊可是真的很难把它和epoll

揉在一起. 因为双方都很意外. epoll 是 61 + 10 分 一个iocp是 90 - 20 分.
假诺强揉就要对 socket 行为

读写链接都急需抽出一层. 不过用 select 只必要抽出 poll
监听触发抽出来就足以了. 中期有时间大家

详细分析 iocp. 当前带我们感受下 epoll 那么些操作.

#include <sys/epoll.h>int epoll_create(int size);int epoll_create1(int flags);epoll_create() creates a new epoll(7) instance. Since Linux 2.6.8, the size argument is ignored, but must be greater than zero; see NOTES below.epoll_create() returns a file descriptor referring to the new epoll instance. This file descriptor is used for all the subse‐quent calls to the epoll interface. When no longer required, the file descriptor returned by epoll_create() should be closed by using close(2). When all file descriptors referring to an epoll instance have been closed, the kernel destroys the instance and releases the associated resources for reuse.epoll_create1()If flags is 0, then, other than the fact that the obsolete size argument is dropped, epoll_create1() is the same as epoll_create(). The following value can be included in flags to obtain different behavior:EPOLL_CLOEXECSet the close-on-exec (FD_CLOEXEC) flag on the new file descriptor. See the description of the O_CLOEXEC flag in open(2) for reasons why this may be useful.

更为切实是

SYSCALL_DEFINE1(epoll_create, int, size){ if (size <= 0) return -EINVAL; return sys_epoll_create1(0);}

从下边可以看出来方今引进的 epoll_create 用法是 

epoll_create1(EPOLL_CLOEXEC)

不再须要 size那一个历史包袱, 并且 exec 重新开进程的时候能够 close 再次回到的
efd 幸免句柄泄漏. 

再有一个就是关于 epoll 的 EPOLLIN 暗许LT水平触发状态, 其它一个是 EPOLLET
边缘触发. 

/* Flags for epoll_create1. */#define EPOLL_CLOEXEC O_CLOEXEC/* Valid opcodes to issue to sys_epoll_ctl() */#define EPOLL_CTL_ADD 1#define EPOLL_CTL_DEL 2#define EPOLL_CTL_MOD 3/* Epoll event masks */#define EPOLLIN 0x00000001#define EPOLLPRI 0x00000002#define EPOLLOUT 0x00000004#define EPOLLERR 0x00000008#define EPOLLHUP 0x00000010/* Set the Edge Triggered behaviour for the target file descriptor */#define EPOLLET (1U << 31)

对此一般服务器例如游戏服务器, 大型Web系统服务器 LT 那种高档 select
操作就足足了.  刚好把验证

代码抛给上层. ET 情势的话就需求在框架的互联网层处理包卓殊.
不过安全的高速度的康庄大道通讯可以品味

一套ET流程交互. epoll 功用尤其好掌握, 注册, 监听, 再次回到结果.
最恶心就是回去结果的操作. 

不妨体现个部分代码 

//// sp_wait - poll 的 wait函数, 等待别人自投罗网// sp : poll 模型// e : 返回的操作事件集// max : e 的最大长度// return : 返回待操作事件长度, <= 0 表示失败//int sp_wait(poll_t sp, struct event e[], int max) { struct epoll_event ev[max]; int i, n = epoll_wait(sp, ev, max, -1); for (i = 0; i < n; ++i) { uint32_t flag = ev[i].events; e[i].s = ev[i].data.ptr; e[i].write = flag & EPOLLOUT; e[i].read = flag & (EPOLLIN | EPOLLHUP); e[i].error = flag & EPOLLERR; } return n;}

一个最简便易行的来得结果, 那里就处理了 EPOLLOUT 和 EPOLLHUP 还有 EPOLLETucson哈弗枚举.

EPOLLHUP 消除 listen -> connect -> accept 占用资源不自由,
空转难点. 其实想想最简单易行的TCP互连网也倒霉搞.

渴求广大 (互联网细节, 是个大工程)


6. 讲的略微泛泛, 文末不妨显示个 不忘初心 

#include <stdio.h>#include <limits.h>#include <stdint.h>//// 强迫症 × 根治// file : len.c// make : gcc -g -Wall -O2 -o love.out love.c// test : objdump -S love.out//int main(int argc, char * argv[]) { const char heoo[] = "Hello World"; for (size_t i = sizeof heoo - 1; i < SIZE_MAX; --i) printf(" %c", heoo[i]); putchar('\n'); return 0;}

后记 - 力求走过


  错误是在所难免的迎接指正. 

      
前几日复出
http://music.163.com/m/song?id=3986241&userid=16529894

       The Carpenters - Yesterday
Once[SD,854x480].mp4
:
https://pan.baidu.com/s/1slA0yU5

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。