关于udp:线上-udp-客户端请求服务端客户端句柄泄漏问题

本题别离从如下三个方面来分享: 问题形容<!----> 自定义连接池的编写<!----> common_pool 的应用问题形容线上有一个业务,某个通服务告诉 udp 客户端通过向 udp 服务端(某个硬件设施)发送 udp 包来进行用户上线操作 当同时有大量的申请打到 udp 服务端的时候,udp 服务端的回包可能会在网络环境中丢包,(udp 是不牢靠的)导致 udp 客户端不能及时的收到 udp 服务端的回包,在短时间内,udp 客户端的句柄又没有失去复用或者开释,没有收到回包的句柄就始终阻塞在那里,最终导致句柄透露 那么能够如何解决呢? 增大客户端的句柄数<!----> 应用连接池并且在读取服务端响应数据时加上超时工夫显然,第一个解决形式治标不治本,改大句柄数,当申请质变大的时候,依然会呈现句柄透露的状况 第二种形式绝对靠谱很多 首先,咱们将发送 udp 包给服务端后,期待读取服务端的回包时,设置超时工夫,超时后读取失败,开释或者偿还句柄<!----> 保护一个外部的连接池,缩小每一次创立句柄耗费的资源和工夫,应用的时候从池子外面获取句柄,应用结束之后再偿还句柄自定义连接池的编写 customer_pool那么对于连接池,咱们实际上是能够本人来进行造轮子的,仅用于学习,理论应用的话,天然还是会去应用通过公众考研过的公共开源库,咱们能够来根本的剖析和钻研一下一个连接池须要有些什么? 创立池子,敞开池子,池子的敞开状态<!----> 从池子中获取连贯,偿还连贯,销毁以后连贯<!----> 池子中能包容的最大连接数,最小连接数,以后连接数<!----> 依据以后理论的连接数来对池子进行扩容和缩容<!----> 池子中创立连贯的函数具体实现当然,咱们本人来领会一下连接池以及演示上述 udp 的 demo,咱们仅实现如下几个简略性能作为演示 创立池子,池子的敞开状态<!----> 从池子中获取连贯,偿还连贯<!----> 池子中能包容的最大连接数,最小连接数,以后连接数<!----> 池子中创立连贯的函数具体实现对于池子中具体链接的销毁,池子的敞开,池子的扩缩容,以及其余高级应用,xdm 能够进行扩大 customer_pool demo自定义连接池,实际上咱们是应用 chan 通道来进行实现,具体源码能够查看:https://github.com/qingconglaixueit/customer_pool/blob/master/customer_pool/pool.go 定义连接池 MyConnPool 数据结构,和创立连接池MyConnPool 构造中的 sync.Mutex 次要是用于管制多协程中 非 pool 成员的其余成员的互斥,咱们晓得 chan 外部是有锁进行管制的 获取对象的具体实现从池子中获取对象,如果获取不到则默认查看以后的池子状态是否能够创立新的连贯<!----> 若能够,则间接创立连贯,返回对象<!----> 此处在进行池子成员的变动时,须要加锁进行管制func (conn *MyConnPool) GetObject() (interface{}, error) { return conn.getObject()}func (conn *MyConnPool) getObject() (interface{}, error) { if conn.isClosed { return nil, errors.New("pool is closed") } // 从通道外面读,如果通道外面没有则新建一个 select { case object := <-conn.pool: return object, nil default: } // 校验以后的连接数是否大于最大连接数,若是,则还是须要从 pool 中取 // 此时应用 mutex 次要是为了锁 MyConnPool 的非通道的其余成员 conn.Lock() if conn.currentConn >= conn.maxConn { object := <-conn.pool conn.Unlock() return object, nil } // 逻辑走到此处须要新建对象放到 pool 中 object, err := conn.connFun() if err != nil { conn.Unlock() return nil, fmt.Errorf("create conn error : %+v", err) } // 以后 pool 已有连接数+1 conn.currentConn++ conn.Unlock() return object, nil}开释对象的具体实现应用结束对象之后,须要偿还<!----> ...

September 5, 2023 · 2 min · jiezi

关于udp:化虹为桥-Nginx-如何代理-UDP-连接

家喻户晓,UDP 并不像 TCP 那样是基于连贯的。但有些时候,咱们须要往一个固定的地址发送多个 UDP 来实现一个 UDP 申请。为了保障服务端可能晓得这几个 UDP 包形成同一个会话,咱们须要在发送 UDP 包时绑定某个端口,这样当网络栈通过五元组(协定、客户端IP、客户端端口、服务端IP、服务端端口)进行辨别时,那几个 UDP 包可能分到一起。通常咱们会把这种景象称之为 UDP 连贯。 但这样又有了一个新的问题。不同于 TCP 那样有握手和挥手,UDP 连贯仅仅意味着应用固定的客户端端口。尽管作为服务端,因为当时就跟客户端约定好了一套固定的协定,能够晓得一个 UDP 连贯该当在何处终止。但如果两头应用了代理服务器,那么代理是如何辨别某几个 UDP 包是属于某个 UDP 连贯呢?毕竟没有握手和挥手作为分隔符,一个中间人是不分明某个会话该当在何处放下句号的。 通过上面的试验,咱们会看到 Nginx 是如何解决这个问题的。 试验在接下来的几个试验中,我都会用一个固定的客户端。这个客户端会向 Nginx 监听的地址建设 UDP “连贯”,而后发送 100 个 UDP 包。 // save it as main.go, and run it like `go run main.go`package mainimport ( "fmt" "net" "os")func main() { conn, err := net.Dial("udp", "127.0.0.1:1994") if err != nil { fmt.Printf("Dial err %v", err) os.Exit(-1) } defer conn.Close() msg := "H" for i := 0; i < 100; i++ { if _, err = conn.Write([]byte(msg)); err != nil { fmt.Printf("Write err %v", err) os.Exit(-1) } }}根底配置上面是试验中用到的 Nginx 根底配置。后续试验都会在这个根底上做些改变。 ...

January 29, 2023 · 4 min · jiezi

关于udp:网络协议之基于UDP的高速数据传输协议UDT

 简介 简略就是美。在网络协议的世界中,TCP和UDP是建设在IP协定根底上的两个十分通用的协定。咱们当初常常应用的HTTP协定就是建设在TCP协定的根底上的。相当于TCP的稳定性来说,UDP因为其数据传输的不可靠性,所以用在某些特定的场合,如直播、播送音讯、视频音频流解决等不太须要校验数据完整性的场合。 UDP绝对TCP协定而言,其特点就是简洁,它删除了在TCP协定中为了保障音讯准确性的各种限制性特色。简洁带来的益处就是快!明天给大家解说一下,基于UDP的高速数据传输协定UDT。 UDT协定 UDP因为其简略的个性,所以能够做到很多TCP做不到的事件,比方进行大数据量的疾速传输。这里并不是要将TCP和UDP分个好坏高下,毕竟各个协定的适应场景不同,他们之所以风行,就是因为能够在特定的场景施展出重要的作用。套用中国的一句谚语就是:不论白猫黑猫,能抓到老鼠的,就是好猫。 用好UDP协定,咱们就能够疾速的传递大量的数据,这个协定就是UDT协定。 话说,像这些根底协定都是老外创造的,而中国的互联网巨头都在抢着做平台、做流量的生意,真的是无话可说…. UDT我的项目开始于2001年,是由Yunhong Gu在芝加哥伊利诺伊大学国家数据挖掘核心 (NCDM)读博士期间开发的,并在毕业之后继续的进行保护和降级改良。 UDP的呈现是因为那时候,传输更快更便宜的光纤网络呈现了,代替了之前的铜缆线和双绞线,从而极大的晋升了信息传输的效率。这时候大家就发现之前应用TCP协定来进行大数据的传输会有很大的问题。从而基于UDP的UDT协定呈现了。 UDT的第一个版本,也称为SABUL(Simple Available Bandwidth Utility Library),UDT通过反对批量数据传输,从而不便在公有网络中进行数据的传输。 要留神的是UDT的第一个版本SABUL应用UDP协定进行传输数据,同时应用独自的TCP协定连贯传输管制音讯。 UDT的初始版本是在超高速网络(1 Gbit/s、10 Gbit/s等)上进行开发和测试的,2003年10月,NCDM实现了从美国芝加哥到荷兰阿姆斯特丹的均匀每秒6.8G比特的传输。在30分钟内的测试中,他们传输了大概1.4TB的数据。 从2004年公布的2.0版本开始,SABUL改名为UDT,UDT的全称是UDP-based Data Transfer Protocol,也就是基于UDP的数据传输协定。 为什么要改成UDT呢?因为在UDT2.0中,删除了SABUL中的TCP 管制连贯,并应用UDP来解决数据和管制信息。 另外,UDT2还引入了一种新的拥塞控制算法,容许协定动静调整UDT和TCP流,实现UDT和TCP流的并发运行。 在2006年,UDT协定降级到了3版本,该协定不仅是在公有网络中运行了,而是扩大到了商业互联网中。同时UDT3中的拥塞管制能够进行调整优化,能够在低带宽的环境中运行,并且容许用户轻松定义和装置本人的拥塞控制算法。另外,UDT3还显着缩小了系统资源(CPU和内存)的应用。 2007年,UDT4版本在高并发和防火墙穿透方面进行优化和性能的晋升。UDT4容许多个UDT连贯绑定到同一个UDP端口,它还反对汇合连贯设置,以便UDP hole punching。 什么是UDP hole punching呢? UDP hole punching通常被用在网络地址转换 (NAT)中。用来保护穿梭NAT的用户UDP数据包流。它是一种应用网络地址转换器在专用网络中的Internet主机之间建设双向UDP连贯的办法。 什么是NAT呢? 大家都晓得IPV4地址是无限的,很快IPV4地址就快用完了,那怎么解决这个问题呢? 当然,一个永恒解决的方法是IPV6,不过IPV6推出这么多年了,如同还没有真正的遍及。 不应用IPV6的话还有什么解决办法呢? 这个方法就是NAT(Network Address Translators)。 ...

May 5, 2022 · 1 min · jiezi

关于udp:我到底是怎么被炸房挂轰炸掉线的

我到底是怎么被"炸房挂"轰炸掉线的?炸房挂?家喻户晓,在一些吃鸡类、MOBA对战类游戏中,咱们常常都会遇到一些”神仙局”,比方在吃鸡,FPS类游戏中常常遇到”枪枪爆头”,在MOBA类游戏中遇到各种对手的技能零CD有限开释,这类型的外挂,都是利用模仿鼠标键盘,或者是截取Sock和API内容,将其批改达到成果的。 而另外一类的外挂,就是要害的对战时刻,间接让玩家网络卡顿甚至掉线了;或者在游戏刚开始的时候,间接让所有玩家掉线,而后通过管制攻打的进行工夫,更快地从新连贯到战斗服中,比方在吃鸡游戏外面,如果游戏刚开始的时候,大家都掉线了,而后60秒后再重连回去,首先重连胜利的玩家(个别是开外挂的玩家,因为他能够管制进行工夫),将能够轻易地将周边的落地玩家击杀,从而获利。这类外挂统称为“炸房挂”,这就是明天次要的话题。 游戏中的UDP协定在即时多人对战类的游戏外面,通常都会应用UDP协定间接让多个玩家连贯到同一局战斗服务器中(同一局对战/正本,会调配到雷同的公网IP地址和端口),所以歹意玩家(开挂)是能够轻易地获取到具体的对战服务器地址和端口的。 DDoS攻打与UDP常见的DDoS攻打伎俩,次要分为两种类型: 管制内部大量的肉机,应用脚本,让这些肉机应用脚本,间接攻打指标服务器。仅须要管制大量的肉机,通过拜访互联网的公共服务,而后通过批改源地址,对指标服务器进行分布式的反射攻打。咱们来比照一下TCP和UDP的协定包构造:咱们能够发现,在UDP的业务流中,并不像TCP那样,有多个字段维度能够检测的。所以总结一下,UDP的次要特点是:无连贯源IP容易伪造(有很多运营商是不会检测源地址是否是本人调配的),难溯源攻打成本低Azure防护计划所以,针对这些攻打,咱们有5种次要的防护思路: 1. 服务器白名单、黑名单只容许业务目标端口,屏蔽常见的反射源端口。 2. 地理位置过滤针对业务用户的地理位置个性,在遇到UDP反射攻打时,优先从用户量起码地理位置的源IP进行封禁阻断,直到将异样地理位置的源IP申请全副封禁,使流量降至服务器可解决的范畴之内,可无效加重烦扰流量。 3. 基于IP和端口的限速通过对源IP、源端口、指标IP、指标端口的多种搭配组合进行限速管制,实现灵便无效的防护策略,升高业务影响范畴。 4. 流量异样稳定克制算法对失常的业务流量进行学习建模,当某类异样流量呈现疾速突增的稳定时,主动判断哪些是异样从而进行限速/封禁,以防止对失常流量造成影响。 5. 指纹(水印)过滤协商好特定的水印算法,在客户端发包的时候带上水印字段,而后通过水印过滤辨认失常还是攻打流量。 而这5种防护的思路,Azure都能提供对应的防护计划。 Network Security GroupAzure Firewall高级定制防护Azure DDoS Standard Plan高级定制防护咱们大抵总结为三道次要的防线: 第一道防线:Azure DDoS Standard Plan启用Azure DDoS规范防护,阻挡大部分的3-4层攻打。 第二道防线:增加水印在手机客户端发送每条信息中都嵌入了水印,而攻打的报文没有携带水印,Azure能够通过这些水印进行过滤,只有携带水印的报文,才会达到后端游戏服务器,从而达到防护的成果。 第三道防线:基于端口的速率限度咱们不能保障水印计划能够100%抵御所有DDoS流量,所以当DDoS依然能够达到后端服务器的时候,咱们能够通过限度每个端口的速率,以就义一局游戏的代价(作废解决),来换取整台服务器上的其余游戏房间的失常运行。

November 4, 2021 · 1 min · jiezi

关于udp:字符数组和字符串基本掌握

/*字符数组把握:strlen,strcat,strcpy,strstr,strcmp*/char c[100]="ZIFUshuzu1",c1[100]="give me five";//字符数组//gets(c);//读入一整行直到换行//cin>>c;//当没有空格//1.长度 strlenint len_c=strlen(c);;cout<<"长度:"<<len_c<<endl;//2.赋值strcpy(c,c1);//把c1赋值给ccout<<"把c1赋值给c:"<<c<<endl;//3.合并(连贯)strcat(c,c1);//c+c1(c1加到c后)cout<<"c1加到c后:"<<c<<endl;/*字符串把握:size(),length()等*/string s,s1;s="ZIFUCHUAN1";s1="good good study";//1.读入一整行(直到换行),包含读入空格// getline(cin,s);//2.size() 求字符串的长度,等同于length()函数s="12 34";cout<<s.size()<<endl;//3.s[下标i] 取字符串的某个字符 ,等同于at(下标i)s="abcd";cout<<s[0]<<s.at(2)<<endl;/*4.substr(开始地位i,子串长度len);取字符串的子串。当len超过原字符串的长度时,只取下剩下的。揭示:i要在字符串长度内。*/s="abcdef";cout<<s.substr(3,2)<<s.substr(3,20)<<endl;/*5.insert(插入地位i,插入字符串s);在字符串第i个地位插入s*/s="abcdef";s.insert(2,"+1234");cout<<s<<endl;/*6.erase(开始地位i,删除菜单len);输入字符串的第i个地位后的len个字符。*/s="abcdef";s.erase(2,3);cout<<s<<endl;/*7.replace(开始地位i,长度len,要换上的字符串ss);用字符串ss替换字符串中i开始的长度是len的一段。*/s="abcdef";s.replace(2,1,"123");cout<<s<<endl;/*8.find(子串subs)查找子串subs第1次呈现的地位,没有找到返回string::nposfind还有一些更弱小的模式,比方在某一段*/s="abcdef";int i=s.find("cd");cout<<i<<endl;return 0;}

August 20, 2021 · 1 min · jiezi

关于udp:教你如何将表格里手机号和座机号分开

金芝号码提取整顿助手,软件作者徽veve188,能够解决题目中的问题,你能够佰渡搜一下它,去电脑上安一个。咱们在平时整顿货色的时候常常遇到这种难题:如何将表格里手机号和座机号离开?excel表格里电话和座机号离开?excel表手机号和座机号离开等相干问题,都能够用它来解决。 把你的excel关上,全副把你的芜杂文本(座机号码手机号文字等)复制好,关上软件“金芝号码提取整顿助手”,粘贴进去,点“独自提取号码”,就能够把11位的手机号独自提取进去,主动删除去除座机号码固定电话号码。省事,省时,省力。工夫就是金钱,借助工具能疾速解决咱们的问题,节约下来的工夫,能够去做重要的工作,发明更多的价值。座机号码和手机号码混在一起怎么拆分?如何将表格里手机号和座机号离开?这个问题,借助软件“金芝号码提取整顿助手”,让您享受解放双手的高兴。

August 17, 2021 · 1 min · jiezi

关于udp:教你如何提取文本文档里的手机号如何从文档中提取电话

软件“金芝号码提取整顿助手”(能够百度搜寻一下)能够解决题目中的问题,如何提取文本文档里的手机号,如何从文档中提取电话的办法解说。也就是咱们的txt文本文档或者word或者excel外面有大量混淆的芜杂的信息,咱们只想独自提取外面的11位手机号码。那么上面解说的操作方法看起来很简略,须要的敌人能够参考上面的办法步骤操作一遍吧,置信会帮大家解决问题的。 这款实用的软件叫做“金芝号码提取整顿助手”,能够百度搜寻一下,进去网站下载,它的第一个性能便是“手机号码独自提取”,它具备智能辨认手机号码的性能。话不多说,简略三步就能够轻松做到你想要的,解放双手。第一步:关上你的txt或者Excel或者Word把你的所有芜杂信息复制,而后到软件找“单纯提取号码”性能,粘贴你的信息到软件上。第二步:点“提取手机号码”,软件就能够自动识别并独自提取进去手机号码,能看到号码提取进去在软件上。第三步:导出txt。号码导出的格局是:txt,一个号码一行,单列。如果想打印进去,倡议应用软件另外的性能:号码打印排版,单列号码主动排版成多行多列,能够导出EXCEL电子表格,很不便间接打印,节约纸张空间。 除了“手机号码提取性能”以外,这个软件还具备另外的便捷性能,能够对提取失去的号码进一步整顿,比方“手机号码去除反复”、“手机号码打乱程序”、“手机号码三网拆散”、“手机号码打印前排版”等,帮您把失去的号码个性化整顿得更好。 这篇文章解说的就是咱们在日常解决数据时候遇到的问题:如何提取文本文档里的手机号,如何从文档中提取电话的办法解说。利用软件“金芝号码提取整顿助手”的话的确能疾速进步咱们的工作效率,省事省力。

August 10, 2021 · 1 min · jiezi

关于udp:LinuxsetROOT

假如有文件夹 mine_dir,想要把它设为管理员能力拜访读写. 更改文件夹拥有者 sudo chown root:root mine_dir递归地将 mine_dir 下的文件权限全设为级别700 sudo chmod -R 700 mine_dir上述2条命令之后,普通用户便无法访问 mine_dir. 若想要拜访,须要变更为管理员用户sudo su 若想切换回普通用户,则: sudo su 普通用户名称

July 22, 2021 · 1 min · jiezi

关于udp:网云穿搭建minecraft我的世界服务端-外网远程联机

休闲工夫想游戏联机,在家和当地敌人联机玩我的世界。然而没有公网ip怎么整?之前测试过几款内网穿透,有的须要本人搭建,很麻烦并且破费不低。有的穿透免费版外网端口不固定老是变,一遍就要从新连贯游戏,十分麻烦;最近找到了一个收费的内网穿透,网云穿内网穿透;在理解了外网端口和域名是固定不变的,所以尝试了一番。感觉挺实用,配置比较简单,下载简略配置就能够让外网的敌人连进来一块开撸。做了一篇教程,有须要的能够参考,教程如下: 所需工具: _*_网云穿内网穿透[我的世界]服务端 我用的是Minecraft 1.6.2版本_*_ 一、关上网云穿官网,注册账号,开明收费隧道 二、配置隧道 1、支付完隧道,会主动跳转控制台,让咱们配置隧道 2、在命令提示符界面,输出ipconfig查看电脑的IP,个别127.0.0.1永远代表本机,填127.0.0.1即可 3、设置服务器配置(端口和ip) 4、回到控制台配置隧道,点击隧道上的配置,填写隧道信息,配置信息如下: ①隧道名称:自定义②隧道地址:127.0.0.1 内网服务器ip ③内网端口:25565 我的世界服务端口 ④二级域名:零碎主动调配 ⑤穿透协定:tcp 配置完点击确定: 三、官网下载网云穿客户端,我的是windows零碎,故下载windows客户端版本(依据本人零碎下载对应版本) ![上传中...]()![上传失败,undefined]() 1、客户端是绿色免装置的,下载解压,双击运行即可 2、登录客户端 登录客户端能够看到,软件调配咱们一个映射地址,咱们先复制映射地址,而后启动隧道 四、在内网测试服务器连贯是否失常 1、开启我的世界服务器 2、在局域网内咱们另找一台电脑,来测试用内网ip和内网端口是否能够连贯上服务 能够看到内网测试能胜利连贯 3、外网连贯测试,看是否能够胜利连贯 在客户端 须要输出服务器地址的中央,输出咱们方才复制的映射地址即可 外网测试连贯胜利,能够邀请小伙伴开撸了,完满实现。

February 23, 2021 · 1 min · jiezi

关于udp:TCP-协议灵魂问题巩固你的网路底层基础

先亮出这篇文章的思维导图 TCP 作为传输层的协定,是一个软件工程师素养的体现,也是面试中常常被问到的知识点。在此,我将 TCP 外围的一些问题梳理了一下,心愿能帮到各位。 001. 能不能说一说 TCP 和 UDP 的区别?首先概括一下根本的区别: TCP是一个面向连贯的、牢靠的、基于字节流的传输层协定。 而UDP是一个面向无连贯的传输层协定。(就这么简略,其它TCP的个性也就没有了)。 具体来剖析,和 UDP 相比,TCP 有三大外围个性: 面向连贯。所谓的连贯,指的是客户端和服务器的连贯,在单方相互通信之前,TCP 须要三次握手建设连贯,而 UDP 没有相应建设连贯的过程。可靠性。TCP 花了十分多的功夫保障连贯的牢靠,这个可靠性体现在哪些方面呢?一个是有状态,另一个是可管制。TCP 会精准记录哪些数据发送了,哪些数据被对方接管了,哪些没有被接管到,而且保障数据包按序达到,不容许半点过错。这是有状态。 当意识到丢包了或者网络环境不佳,TCP 会依据具体情况调整本人的行为,管制本人的发送速度或者重发。这是可管制。 相应的,UDP 就是无状态, 不可控的。 面向字节流。UDP 的数据传输是基于数据报的,这是因为仅仅只是继承了 IP 层的个性,而 TCP 为了保护状态,将一个个 IP 包变成了字节流。002: 说说 TCP 三次握手的过程?为什么是三次而不是两次、四次?恋爱模仿以谈恋爱为例,两个人可能在一起最重要的事件是首先确认各自爱和被爱的能力。接下来咱们以此来模仿三次握手的过程。 第一次: 男: 我爱你。 女方收到。 由此证明男方领有爱的能力。 第二次: 女: 我收到了你的爱,我也爱你。 男方收到。 OK,当初的状况阐明,女方领有爱和被爱的能力。 第三次: 男: 我收到了你的爱。 女方收到。 当初可能保障男方具备被爱的能力。 由此残缺地确认了单方爱和被爱的能力,两人开始一段苦涩的恋情。 实在握手当然刚刚那段属于扯淡,不代表自己价值观,目标是让大家了解整个握手过程的意义,因为两个过程十分类似。对应到 TCP 的三次握手,也是须要确认单方的两样能力: 发送的能力和接管的能力。于是便会有上面的三次握手的过程: 从最开始单方都处于CLOSED状态。而后服务端开始监听某个端口,进入了LISTEN状态。 而后客户端被动发动连贯,发送 SYN , 本人变成了SYN-SENT状态。 服务端接管到,返回SYN和ACK(对应客户端发来的SYN),本人变成了SYN-REVD。 之后客户端再发送ACK给服务端,本人变成了ESTABLISHED状态;服务端收到ACK之后,也变成了ESTABLISHED状态。 另外须要揭示你留神的是,从图中能够看出,SYN 是须要耗费一个序列号的,下次发送对应的 ACK 序列号要加1,为什么呢?只须要记住一个规定: ...

February 18, 2021 · 5 min · jiezi

关于udp:颜小熙听孙秀花絮絮叨叨地说了这些事情

颜小熙的眉头皱了皱,这个小媳妇不是刚刚说回去喊人的三婶。 她有点想晓得,三婶去哪里了?看到她们,那小媳妇停下脚步,神气凝重地看着李梅英问道:“梅英姐,你生啦?”李梅英快乐地点了拍板,“是个儿子……”话音刚落,她就又哭了起来。“相公可算是有后了!”她的相公颜北斗年前被朝廷征兵给征走了,没想到前几天,村子里有人接到了家书,说她相公战死沙场了。若非是肚子里还怀着个孩子,她顾念着要把这个孩子平安地生下来,这才没怎么哭闹,刚强地撑了下来。却没想到相公不在了,没人给她撑腰,大姑子和婆婆居然打起了卖她女儿的主见。“快别哭了!”那小媳妇连忙刺激她。“你刚生了孩子,可千万不能哭,要是回了奶,回头孩子就没吃的了。”李梅英连忙收住眼泪,“秀花妹子,你咋来了?你不是回娘家喝喜酒去了吗?”“我刚到家,半路上碰到了我公公,他上你家去给你爹娘送信了,我据说了你家的事,我就连忙过去瞧瞧,后果在村子口遇到你们家三婶,她跟我说你要生了,我就连忙回去把我相公和小叔子都叫了来。”孙秀花说着,指挥身后那两个男人。“你们把架子撑好了,让梅英姐躺上去。”李梅英有点不好意思,“不必了,我本人能走。”“别胡闹了!”那小媳妇杂色斥责她。“你才刚生了孩子,基本就不能下地,听我的,把孩子给我,你刚生产完,身子虚,别把孩子摔了。”李梅英只好听她的,让她扶着本人躺到担架上,“秀花妹子,谢谢你了。”这小媳妇名叫孙秀花,同李梅英的娘家是一个村子的,二人打小交好,长大了又嫁到了一处,平时始终都是互相呼应的。“快别说这些客气话了,咱们先回家。”这孙秀花也是个爽利人,连忙打发自家男人和小叔子抬了她回去。颜小熙在一旁问道:“婶子,那我三婶呢?”孙秀花从鼻孔里收回一声冷嗤,“你三叔把她拽回家,不让她跟着来。”说着,她抬头看着颜小熙,眼中满是讶异,“二妮子,不是说你死了吗?怎么又活过来了?”颜小熙赶紧道:“我就是撞到头,晕过去了,才没死!”她才不会通知旁人,本人是个穿梭女的事。孙秀花这才松了一口气,小声道:“幸好你没事,不然的话,可真是坑死你娘了。”他们住的村子间隔这个乱葬岗大概得有五里地,此时正是初夏节令,地里曾经冒出了绿油油的麦苗。村子里稀稀落落的有上百户人家,这会子正是黄昏,远远地能够看见不少人家的烟囱里冒出了灰白色的炊烟。孙秀花一边走,一边小声骂道:“你们家大姑也真不是个货色,他大姑父都考了那么些年了,也没考个举人进去,本人个儿不争气,却糊弄着你公公婆婆给供养他。那年卖了你小姑子给他凑盘缠,这一次又卖了大妮子。你们家老爷子和老太太这心也够狠的,本人的亲闺女、亲孙女说卖就卖……”李梅英没谈话,不过紧闭的眼睛里却淌出两行泪。颜小熙听孙秀花絮絮叨叨地说了这些事件,心中微叹,她不太理解这里的法律,所以不敢轻易倡议,在古代,若是有这样的事件,就间接上法院起诉了,这可是交易人口!然而这里是现代,她尽管不晓得这里是什么朝代,然而却晓得,现代交易人口是齐全非法的。而且,现代律法规定,前辈立功,家中长辈不能去衙门告发检举,反而要帮忙瞒哄,不然的话,即使前辈真的有罪,去告发检举的人也要坐牢放逐,或者承受杖刑。卖掉她姐姐的是她的爷爷奶奶,她和她娘是相对不能通过法律路径来讨回这个公平。然而这件事件她不可能就这么算了,尽管她不是这具身材的本尊,然而现如今,她既然曾经占据了这具身材,就得担负起爱护这个家的职责。她得好好地推敲推敲,要怎样才能讨回这个公平!不然的话,下一次被卖的人就会是她了。

December 19, 2020 · 1 min · jiezi

关于udp:王者荣耀如何使用UDP做到低延迟

https://www.bilibili.com/vide...

December 2, 2020 · 1 min · jiezi

关于udp:UDP的epoll并发框架解决OpenUOM的并发问题

UDP具备是一种很好的封装协定,比方OpenUOM应用UDP封装会比TCP好很多,当初越来越多的业务采纳UDP传输,而后本人定义按序达到以及流控逻辑,然而就我集体的应用教训来看,UDP太难做并发,大多数状况下,应用UDP会让epoll等高性能event机制劣势全无。本文以OpenUOM为例,阐明一下我是怎么解决UDP并发问题的。 异步并发模型与epoll和apache相比,nginx采纳异步的解决形式,也就是说,一个线程能够解决多个连贯,基于event模型,来了个数据包就读,可能顺次达到的数据不属于同一个连贯,然而没关系,只有能将可读的socket描述符和具体的连贯对应上即可。这样会使得在大并发场景下,让CPU迫近其极限运行,因为它简直没有工夫闲着,它会始终解决达到的数据包。apache的模型就不是这样,它会让一个连贯独自占有一个线程,如果有大量的连贯就会有大量的线程,然而对于每一个线程而言,其数据读写的压力并不是很大,这就会导致大量线程之间频繁切换,而切换会导致cache的刷新等副作用...因而在同样的硬件配置情景下,nginx的异步模型要比apache好很多。 咱们曾经晓得,异步解决是搞定大并发的基本,接下来的问题是,如何让一个就绪的socket和一个业务逻辑连贯对应起来,这个问题在同步模型下并不存在,因为一个线程只解决一个连贯。已经的event机制比方select,poll,它们只能通知你socket n就绪了,你不得不本人去通过数据结构来组织socket n和该连贯信息之间的关系,典型的如下: struct conn { int sd; void *others;};list conns;一个链表conns囊括了该线程负责的所有连贯,如果select/poll通知你socket n就绪了,你不得不遍历这个conns链表,比拟谁的sd是n,而后取出conn来解决,尽管能够用更加高效的数据结构,然而查找是必不可少的。然而epoll解决了这个问题。 在调用epoll_ctrl将一个socket退出到epoll中时,API会为你提供一个指针,让你间接绑定一个socket描述符和一个指针,一旦socket就绪,取出的是一个构造体,其中蕴含了与该socket对应的指针,因而你便能够这么做: conn.sd = sd;conn.others = all;ev.events = EPOLLIN;ev.data.ptr = &conn;epoll_ctl(kdpfd, EPOLL_CTL_ADD, sd, &ev);while (1) { nfds = epoll_wait(kdpfd, events, 10000, -1); for (n = 0; n < nfds; ++n) { conn = events[n].data.ptr; recv(conn.sd, ....); .... }}conn会一下子取出来。这是正当的形式。毕竟,内核中曾经通过socket查找了,一个5元组惟一代表了一个连贯,为何要在用户态程序再找一次呢?因而除了epoll不须要遍历所有的被监督socket之外,能够保留用户的指针也是其绝对于select/poll的一大劣势。nginx正是用的这种形式。咱们回到OpenUOM。 应用TCP的OpenUOM应用TCP的OpenUOM跟nginx简直是截然不同,其外围解决逻辑如下: /* 退出侦听socket */context.sd = listener;context.others = dont_care;listen_ev.events = EPOLLIN;listen_ev.data.ptr = context;epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &listen_ev);/* 退出TUN网卡 */tun.sd = tun;tun.others = dont_care;entry.ptr = tun;entry.type = TUN;tun_ev.events = EPOLLIN;tun_ev.data.ptr = entry;epoll_ctl(kdpfd, EPOLL_CTL_ADD, tun, &tun_ev);while(1) { nfds = epoll_wait(kdpfd, events, 10000, -1); for (n = 0; n < nfds; ++n) { if (events[n].data.ptr == context) { child_sd = accept(context.sd, remote_addr....); multi_instance *mi = create_mi(child_sd, remote_addr, ...); entry.ptr = mi; entry.type = SOCKET; new_ev.events = EPOLLIN; new_ev.data.ptr = entry; epoll_ctl(kdpfd, EPOLL_CTL_ADD, child_sd, &new_ev); .... } else if (events[n].data.ptr.type == SOCKET){ multi_instance *mi = events[n].data.ptr; data = read_from_socket(mi); // 这里简化了解决,因为并不是每一个数据包都是须要加密解密的,还有管制通道的包 decrypt(mi, data); write_to_tun(data); } else { tun *tun = events[n].data.ptr.ptr; packet = read_from_tun(tun); lock(mi_hashtable); multi_instance *mi = lookup_multi_instance_from(packet); unlock(mi_hashtable); encrypt(packet); write_to_socket(packet, mi); } } ...}以上就是TCP模式下的OpenUOM全副逻辑,能够看到,如果socket可读,那么就能够间接取到multi_instance,而后程序解决就是了。我记得去年我就把OpenUOM改成多线程了,然而当初看来那是个失败的做法。如果应用TCP,从上述逻辑能够看到,就算应用多线程,在socket-to-tun这个门路上也不必加锁,因而multi_instance间接通过epoll_wait就能够取的到。 ...

November 17, 2020 · 5 min · jiezi