最新要闻
- 天天百事通!3888元 + 可叠加百亿补贴:天猫无门槛红包12点正式开抢
- 4条狼青犬咬死几十只羊!警惕:性情凶狠、攻击性非常强
- 全球微头条丨211文科硕士吐槽均薪5500引争议:文科生转码或成趋势 还是理科香?
- 报道:“RNG老板道歉”登热搜 CEO:轮换中单是我的决定
- 【世界播资讯】李想:理想汽车要占20万元以上市场35% 将对标苹果特斯拉
- 垂头丧气的丧是什么意思?关于垂头丧气的反义词有哪些?
- 父亲的兄弟如何称呼?写给父亲的一封信作文模板
- 张靓颖的海豚音是哪首歌?张靓颖终于等到你的歌词是什么?
- 李想:如果不卖电池 电动车成本可以比燃油车低
- 热议:马斯克最疯计划曝光!给我10万亿美元:可拯救地球
- 梅西花百万买苹果手机送给阿根廷队友:定制了35部24K金的iPhone 14 Pro
- 天天微头条丨河南小伙1:1打造歼10战斗机模型!司机:这辈子拉过最硬的货
- 每日简讯:奇瑞背刺长城 捷途旅行者实车亮相:10多万的“硬汉”登场
- 早晨问候客户的正能量句子有哪些?早晨问候语有哪些?
- 仓央嘉措是哪个朝代的?仓央嘉措经典诗句有哪些?
- 全球快讯:带有雨的诗句有哪些_带有雨的诗句具体有哪些
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
【播资讯】不为人知的网络编程(十五):深入操作系统,一文搞懂Socket到底是什么
1、引言
我相信大家刚开始学网络编程中socket的时候,都跟我一样对书上所讲的socket概念云里雾里的、似懂非懂,很是困扰。
(资料图片仅供参考)
这篇文章我打算从初学者的角度,用通俗易懂的文字,跟大家分享下我所理解的socket是什么,并由浅入深从操作系统内核实现来透视socket的原理。
* 推荐阅读:跟本篇类似,《到底什么是Socket?一文即懂!》一文也非常适合初学者。另一篇《我们在读写Socket时,究竟在读写什么?》,相信可进一步为你解惑。
学习交流:
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地址点此)
(本文已同步发布于:http://www.52im.net/thread-4146-1-1.html)
2、系列文章
本文是系列文章中的第15篇,本系列文章的大纲如下:
- 《不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)》
- 《不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)》
- 《不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT》
- 《不为人知的网络编程(四):深入研究分析TCP的异常关闭》
- 《不为人知的网络编程(五):UDP的连接性和负载均衡》
- 《不为人知的网络编程(六):深入地理解UDP协议并用好它》
- 《不为人知的网络编程(七):如何让不可靠的UDP变的可靠?》
- 《不为人知的网络编程(八):从数据传输层深度解密HTTP》
- 《不为人知的网络编程(九):理论联系实际,全方位深入理解DNS》
- 《不为人知的网络编程(十):深入操作系统,从内核理解网络包的接收过程(Linux篇)》
- 《不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密》
- 《不为人知的网络编程(十二):彻底搞懂TCP协议层的KeepAlive保活机制》
- 《不为人知的网络编程(十三):深入操作系统,彻底搞懂127.0.0.1本机网络通信》
- 《不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!》
- 《不为人知的网络编程(十五):深入操作系统,一文搞懂Socket到底是什么》(* 本文)
3、初识socket
故事要从一个插头说起。
▲ 插头与插座
当我将插头插入插座,那看起来就像是将两者连起来了。
▲风扇与电力系统建立"连接"
而插座的英文,又叫socket。巧了,我们程序员搞网络编程时也会用到一个叫socket的东西。
其实两者非常相似。通过socket,我们可以与某台机子建立"连接",建立"连接"的过程,就像是将插口插入插槽一样。
大概概念是了解了,但我相信各位对socket其实还是很模糊。接下来我们从大家最熟悉的使用场景开始说起。
4、socket的典型使用场景
我们想要将数据从A电脑的某个进程发到B电脑的某个进程。
这时候我们需要选择将数据发过去的方式,如果需要确保数据要能发给对方,那就选可靠的TCP协议(见《快速理解TCP协议一篇就够》),如果数据丢了也没关系,看天意,那就选择不可靠的UDP协议(见《一泡尿的时间,快速搞懂TCP和UDP的区别》)。
初学者毫无疑问,首选TCP。(见《快速理解TCP和UDP的差异》)
▲TCP是什么
那这时候就需要用socket进行编程。
于是第一步就是创建个关于TCP的socket,就像下面这样:
1sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
上面这个方法会返回socket_fd,它是socket文件的句柄,是个数字,相当于socket的身份证号。
得到了socket_fd之后,对于服务端,就可以依次执行bind(), listen(), accept()方法,然后坐等客户端的连接请求。
对于客户端,得到socket_fd之后,你就可以执行connect()方法向服务端发起建立连接的请求,此时就会发生TCP三次握手(如下图所示)。
▲握手建立连接流程
连接建立完成后,客户端可以执行send() 方法发送消息,服务端可以执行recv()方法接收消息,反过来,服务器也可以执行send(),客户端执行recv()方法。
到这里为止,就是我们大部分程序员最熟悉的使用场景。
PS:限于篇幅,本篇不展开TCP协议的3次握手原理,有兴趣可以详读:《理论经典:TCP协议的3次握手与4次挥手过程详解》、《跟着动画来学TCP三次握手和四次挥手》。
5、socket该怎么设计?
5.1基本认知
现在,socket我们见过,也用过,但对大部分程序员来说,它是个黑盒。
那既然是黑盒,我们索性假设我们忘了socket。重新设计一个内核网络传输功能。
网络传输,从操作上来看,无非就是发数据和远端之间互相收发数据(也就是对应着写数据和读数据)。
▲ 读写收发
但显然,事情没那么简单。
这里有两个问题:
- 1)接收端和发送端可能不止一个,因此我们需要一些信息做下区分,这个大家肯定很熟悉,可以用IP和端口。IP用来定位是哪台电脑,端口用来定位是这台电脑上的哪个进程;
- 2)发送端和接收端的传输方式有很多区别,可以是可靠的TCP协议,也可以是不可靠的UDP协议,甚至还需要支持基于icmp协议的ping命令。
5.2sock的基本定义
写过代码的都知道,为了支持这些功能,我们需要定义一个数据结构去支持这些功能。这个数据结构,叫sock。
为了解决上面的第一个问题,我们可以在sock里加入IP和端口字段:
▲ sock加入IP和端口字段
而第二个问题:我们会发现这些协议虽然各不相同,但还是有一些功能相似的地方,比如收发数据时的一些逻辑完全可以复用。按面向对象编程的思想,我们可以将不同的协议当成是不同的对象类(或结构体),将公共的部分提取出来,通过"继承"的方式,复用功能。
5.3基于各种sock实现网络传输功能
于是,我们将功能重新划分下,定义了一些数据结构:
▲ 继承sock的各类sock
sock是最基础的结构,维护一些任何协议都有可能会用到的收发数据缓冲区。
inet_sock特指用了网络传输功能的sock,在sock的基础上还加入了TTL,端口,IP地址这些跟网络传输相关的字段信息。说到这里大家就懵了,难道还有不是用网络传输的?有,比如Unix domain socket,用于本机进程之间的通信,直接读写文件,不需要经过网络协议栈。这是个非常有用的东西,我以后一定讲讲(画饼)。
inet_connection_sock 是指面向连接的sock,在inet_sock的基础上加入面向连接的协议里相关字段,比如accept队列,数据包分片大小,握手失败重试次数等。虽然我们现在提到面向连接的协议就是指TCP,但设计上linux需要支持扩展其他面向连接的新协议,
tcp_sock 就是正儿八经的tcp协议专用的sock结构了,在inet_connection_sock基础上还加入了tcp特有的滑动窗口、拥塞避免等功能。同样udp协议也会有一个专用的数据结构,叫udp_sock。
好了,现在有了这套数据结构,我们将它们跟硬件网卡对接一下,就实现了网络传输的功能。
5.4提供socket层
可以想象得到,这里面的代码肯定非常复杂,同时还操作了网卡硬件,需要比较高的操作系统权限,再考虑到性能和安全,于是决定将它放在操作系统内核里。
既然网络传输功能做在内核里,那用户空间的应用程序想要用这部分功能的话,该怎么办呢?
这个好办,本着不重复造轮子的原则,我们将这部分功能抽象成一个个简单的接口。以后别人只需要调用这些接口,就可以驱动我们写好的这一大堆复杂的数据结构去发送数据。
那么问题来了,怎么样将这部分功能暴露出去呢?让其他程序员更方便的使用呢?
既然跟远端服务端进程收发数据可以抽象为“读和写”,操作文件也可以抽象为"读和写",正好有句话叫,"linux里一切皆是文件",那我们索性,将内核的sock封装成文件就好了。创建sock的同时也创建一个文件,文件有个句柄fd,说白了就是个文件系统里的身份证号码,通过它可以唯一确定是哪个sock。
这个文件句柄fd其实就是 sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 里的sock_fd。
将句柄暴露给用户,之后用户就可以像操作文件句柄那样去操作这个sock句柄。在用户空间里操作这个句柄,文件系统就会将操作指向内核sock结构。
是的,操作这个特殊的文件就相当于操作内核里对应的sock:
▲ 通过文件找到sock
有了sock_fd句柄之后,我们就需要提供一些接口方法,让用户更方便的实现特定的网络编程功能。这些接口,我们列了一下,发现需要有send(),recv(),bind(), listen(),connect()这些。
到这里,我们的内核网络传输功能就算设计完成了。
现在是不是眼熟了,上面这些接口方法其实就是socket提供出来的接口。
所以说:socket其实就是个代码库 or 接口层,它介于内核和应用程序之间,提供了一些高度封装过的接口,让我们去使用内核网络传输功能。
▲ 基于sock实现网络传输功能
到这里,我们应该明白了。我们平时写的应用程序里代码里虽然用了socket实现了收发数据包的功能,但其实真正执行网络通信功能的,不是应用程序,而是linux内核。相当于应用程序通过socket提供的接口,将网络传输的这部分工作外包给了linux内核。
这听起来像不像我们最熟悉的前后端分离的服务架构,虽然这么说不太严谨,但看上去linux就像是被分成了应用程序和内核两个服务。内核就像是后端,暴露了好多个api接口,其中一类就是socket的send()和recv()这些方法。应用程序就像是前端,负责调用内核提供的接口来实现想要的功能。
▲ 进程通过socket调用内核功能
看到这里,我担心大家会有点混乱,下面来做个小的总结。
5.5小结一下
在操作系统内核空间里,实现网络传输功能的结构是sock,基于不同的协议和应用场景,会被泛化为各种类型的xx_sock,它们结合硬件,共同实现了网络传输功能。
为了将这部分功能暴露给用户空间的应用程序使用,于是引入了socket层,同时将sock嵌入到文件系统的框架里,sock就变成了一个特殊的文件,用户就可以在用户空间使用文件句柄,也就是socket_fd来操作内核sock的网络传输能力。
这个socket_fd是一个int类型的数字。
现在回去看socket的中文翻译,套接字,我将它理解为一套用于连接的数字,是不是就觉得特别合理了。
▲网络分层与基于sock实现网络传输功能
6、socket如何实现网络通信
6.1概述
上面关于怎么实现网络通信功能这一块一笔带过了。本节我们就来详细聊聊。
这套sock的结构其实非常复杂。我们以最常用的TCP协议为例,简单了解下它是怎么实现网络传输功能的。
我将它分为两阶段,分别是建立连接和数据传输。
6.2建立连接
对于TCP,要传数据,就得先在客户端和服务端中间建立连接。
在客户端,代码执行socket提供的connect(sockfd, "ip:port")方法时,会通过sockfd句柄找到对应的文件,再根据文件里的信息指向内核的sock结构。
通过这个sock结构主动发起三次握手:
▲ TCP三次握手
在服务端握手次数还没达到"三次"的连接,叫半连接,完成好三次握手的连接,叫全连接。它们分别会用半连接队列和全连接队列来存放,这两个队列会在你执行listen()方法的时候创建好。
当服务端执行accept()方法时,就会从全连接队列里拿出一条全连接:
▲半连接队列和全连接队列
至此,连接就算准备好了,之后,就可以开始传输数据。
6.3数据传输
为了实现发送和接收数据的功能,sock结构体里带了一个发送缓冲区和一个接收缓冲区,说是缓冲区,但其实就是个链表,上面挂着一个个准备要发送或接收的数据。
当应用执行send()方法发送数据时,同样也会通过sock_fd句柄找到对应的文件,根据文件指向的sock结构,找到这个sock结构里带的发送缓冲区,将数据会放到发送缓冲区,然后结束流程,内核看心情决定什么时候将这份数据发送出去。
接收数据流程也类似,当数据送到linux内核后,数据不是立马给到应用程序的,而是先放在接收缓冲区中,数据静静躺着,卑微的等待应用程序什么时候执行recv()方法来拿一下。就像我的文章,躺在你的推文列表里,卑微的等一个点赞关注转发三连。懂?
▲ sock的发送和接收缓冲区
PS:IP和端口其实不在sock下,而在inet_sock下,上面这么画只是为了简化。
那么问题来了,发送数据是应用程序主动发起,这个大家都没问题。那接收数据呢?数据从远端发过来了,怎么通知并给到应用程序呢?
这就需要用到等待队列:
▲ sock内的等待队列
当你的应用进程执行recv()方法尝试获取(阻塞场景下)接收缓冲区的数据时:
- 1)如果有数据,那正好,取走就好了。这点没啥疑问;
- 2)但如果没数据,就会将自己的进程信息注册到这个sock用的等待队列里,然后进程休眠。如果这时候有数据从远端发过来了,数据进入到接收缓冲区时,内核就会取出sock的等待队列里的进程,唤醒进程来取据。
▲ recv时无数据进程进入等待队列
有时候,你会看到多个进程通过fork的方式,listen了同一个socket_fd。在内核,它们都是同一个sock,多个进程执行listen()之后,都嗷嗷等待连接进来,所以都会将自身的进程信息注册到这个socket_fd对应的内核sock的等待队列中。
如果这时真来了一个连接,是该唤醒等待队列里的哪个进程来接收连接呢?
这个问题的答案比较有趣:
- 1)在linux 2.6以前,会唤醒等待队列里的所有进程。但最后其实只有一个进程会处理这个连接请求,其他进程又重新进入休眠,这些被唤醒了又无事可做最后只能重新回去休眠的进程会消耗一定的资源。就好像你在广东的街头,想问路,叫一声靓仔,几十个人同时回头,但你其实只需要其中一个靓仔告诉你路该怎么走。你这种一不小心惊动这群靓仔的场景,在计算机领域中,就叫惊群效应;
- 2)在linux 2.6之后,只会唤醒等待队列里的其中一个进程。是的,socket监听的惊群效应问题被修复了。
▲ 惊群效应
看到这里,问题又来了。
服务端 listen 的时候,那么多数据到一个 socket 怎么区分多个客户端的?
以TCP为例,服务端执行listen方法后,会等待客户端发送数据来。客户端发来的数据包上会有源IP地址和端口,以及目的IP地址和端口,这四个元素构成一个四元组,可以用于唯一标记一个客户端。
PS:其实说四元组并不严谨,因为过程中还有很多其他信息,也可以说是五元组。。。但大概理解就好,就这样吧。
▲ 四元组
服务端会创建一个新的内核sock,并用四元组生成一个hash key,将它放入到一个hash表中。
▲ 四元组映射成hash键
下次再有消息进来的时候,通过消息自带的四元组生成hash key再到这个hash表里重新取出对应的sock就好了。所以说服务端是通过四元组来区分多个客户端的。
▲ 多个hash_key对应多个客户端
7、sock怎么实现"继承"?
大家都知道linux内核是C语言实现的,而C语言没有类也没有继承的特性,是怎么做到"继承"的效果的呢?
在C语言里,结构体里的内存是连续的,将要继承的"父类",放到结构体的第一位。
就像下面这样:
structtcp_sock {
/* inet_connection_sock has to be the first member of tcp_sock */
structinet_connection_sock inet_conn;
// 其他字段
}
structinet_connection_sock {
/* inet_sock has to be the first member! */
structinet_sock icsk_inet;
// 其他字段
}
然后我们就可以通过结构体名的长度来强行截取内存,这样就能转换结构体,从而实现类似"继承"的效果。
如下代码所示:
// sock 转为 tcp_sock
staticinlinestructtcp_sock *tcp_sk(conststructsock *sk)
{
return(structtcp_sock *)sk;
}
▲ 内存布局
8、本文小结
写到这里,文章就算是结束了,我们来总结一下。
1)socket中文套接字,我理解为一套用于连接的数字。并不一定准确,欢迎评论。
2)sock在内核,socket_fd在用户空间,socket层介于内核和用户空间之间。
3)在操作系统内核空间里,实现网络传输功能的结构是sock,基于不同的协议和应用场景,会被泛化为各种类型的xx_sock,它们结合硬件,共同实现了网络传输功能。为了将这部分功能暴露给用户空间的应用程序使用,于是引入了socket层,同时将sock嵌入到文件系统的框架里,sock就变成了一个特殊的文件,用户就可以在用户空间使用文件句柄,也就是socket_fd来操作内核sock的网络传输能力。
4)服务端可以通过四元组来区分多个客户端。
5)内核通过c语言"结构体里的内存是连续的"这一特点实现了类似继承的效果。
推荐阅读:跟本篇类似,《到底什么是Socket?一文即懂!》一文也非常适合初学者。另一篇《我们在读写Socket时,究竟在读写什么?》,相信可进一步为你解惑。
9、参考资料
[1]到底什么是Socket?一文即懂!
[2]我们在读写Socket时,究竟在读写什么?
[3]通俗易懂-深入理解TCP协议(上):理论基础
[4]快速理解TCP协议一篇就够
[5]假如你来设计TCP协议,会怎么做?
[6]一泡尿的时间,快速搞懂TCP和UDP的区别
[7]快速理解TCP和UDP的差异
[8]理论经典:TCP协议的3次握手与4次挥手过程详解
[9]跟着动画来学TCP三次握手和四次挥手
[10]手把手教你写基于TCP的Socket长连接
[11]为什么QQ用的是UDP协议而不是TCP协议?
[12]移动端即时通讯协议选择:UDP还是TCP?
(本文已同步发布于:http://www.52im.net/thread-4146-1-1.html)
-
【播资讯】不为人知的网络编程(十五):深入操作系统,一文搞懂Socket到底是什么
这篇文章我打算从初学者的角度,用通俗易懂的文字,跟大家分享下我所理解的socket是什么,并由浅入深从...
来源: 【播资讯】不为人知的网络编程(十五):深入操作系统,一文搞懂Socket到底是什么
轻松玩转makefile | 变量与模式
天天百事通!3888元 + 可叠加百亿补贴:天猫无门槛红包12点正式开抢
4条狼青犬咬死几十只羊!警惕:性情凶狠、攻击性非常强
全球微头条丨211文科硕士吐槽均薪5500引争议:文科生转码或成趋势 还是理科香?
报道:“RNG老板道歉”登热搜 CEO:轮换中单是我的决定
【世界播资讯】李想:理想汽车要占20万元以上市场35% 将对标苹果特斯拉
垂头丧气的丧是什么意思?关于垂头丧气的反义词有哪些?
头条焦点:百分比堆叠柱状图适用情形有哪些?速戳!
父亲的兄弟如何称呼?写给父亲的一封信作文模板
张靓颖的海豚音是哪首歌?张靓颖终于等到你的歌词是什么?
李想:如果不卖电池 电动车成本可以比燃油车低
热议:马斯克最疯计划曝光!给我10万亿美元:可拯救地球
梅西花百万买苹果手机送给阿根廷队友:定制了35部24K金的iPhone 14 Pro
天天微头条丨河南小伙1:1打造歼10战斗机模型!司机:这辈子拉过最硬的货
每日简讯:奇瑞背刺长城 捷途旅行者实车亮相:10多万的“硬汉”登场
早晨问候客户的正能量句子有哪些?早晨问候语有哪些?
仓央嘉措是哪个朝代的?仓央嘉措经典诗句有哪些?
蓝码健康码是什么意思?蓝码健康码是正常的吗?
32开纸是多大?32开纸有多大是几个A4?
ps字体怎么加描边?ps字体太小怎么调大?
移动硬盘参数怎么看?移动硬盘参数错误怎么解决?
usd是什么意思?usdt属于什么币种?
全球快讯:带有雨的诗句有哪些_带有雨的诗句具体有哪些
环球观焦点:WebLogic JNDI注入(CVE-2021-2109)
天天通讯!Java 根据模板导出PDF
从菜鸟程序员到高级架构师,竟然是因为这个字final
剑指 Offer 64. 求 1 + 2 + … + n(java解题)
当前简讯:浙江女子1600公里追到广州找到被偷的爱猫:苹果AirTag定位器立了大功
比亚迪豪华MPV成了!腾势D9上月热销7325台:均价41.5万
简讯:俞敏洪最新演讲:不喜欢《狂飙》 企业家只想赚钱就会像高启强后患无穷
复旦MOSS团队:取名是致敬《流浪地球2》 参数规模约ChatGPT的1/10
世界热推荐:跑着跑着会熄火 日产北美召回超80万辆奇骏:车钥匙背锅
环球头条:Git介绍下载安装以及基本使用
全球新消息丨解释器模式
每日时讯!promethues【centos7】时间同步
What is Point ?
【全球新要闻】那舅特大桥建成 又一时速350高铁开铺 南宁至玉林仅50分钟
3899元起 惠普战66六代锐龙版上架:锐龙7000系列加持
世界热议:3月17日开启Beta测试!《暗黑破坏神4》新预告片透露更多游戏内容
焦点短讯!拳头《无畏契约》3月14日起不再支持Win7/8/8.1系统:为了打击外挂!
论文阅读笔记(四):AS-MLP AN AXIAL SHIFTED MLP ARCHITECTUREFOR VISION
(数据库系统概论|王珊)第七章数据库设计-第五、六节:物理结构设计和数据库的实施和维护
全球消息!苹果何时大降价?iPhone 14 Plus成系列销量最差:用户宁愿买安卓
焦点信息:寓言诚不欺我!网友拍下现实版“乌鸦喝水”
焦点报道:儿子篮球班倒闭家长花1000万买下 网友:这就是钞能力
全球热议:999元卷王小金刚!优派推出VX2758显示器:27英寸2K/170Hz
15万就能买特斯拉?特斯拉宣布重大目标:成本降低50%
哪吒汽车2月份交付10073台 同比大涨41.5%
未成年人沉迷短视频得治 TikTok默认限制每天可刷一小时
“自己造自己” 特斯拉人形机器人亮相!马斯克承认罕见事实
【世界速看料】腾讯新游《黎明觉醒:生机》开放60帧:骁龙888、iPhone 13以上都能开
每日视点!印度男子展示绝技“乌鸦召唤术” 网友:在古代至少巫师级别
读Java性能权威指南(第2版)笔记06_数据库性能JPA&SpringData
全省严查!正在进行!
每日看点!马斯克大力推荐!特斯拉Cybertruck实车亮相:超级未来感
天天消息!马斯克宏图计划公布:储能240TWh 制造投资10万亿美元
日本死亡人数是新生儿数量两倍有多可怕:850万“幽灵屋”遍布全国
信息:特斯拉下一代电机将不需要任何稀土成分!马斯克挑战全球车企
环球新动态:Spark系列 - (5) Spark Shuffle
热消息:Fireasy3 揭秘 -- 万物伊始(依赖注入与服务发现)
全球信息:英语四级阅读技巧
一加Ace 2V 12+256G起步行业罕见:友商还在搞8+128卡价位的版本
实时:Redmi Note 12 Pro极速版12+256G到手1999元:开机就是MIUI 14
造车新势力2月交付量出炉:理想、蔚来、哪吒破万 零跑压力大
【全球速看料】厦门征求意见!过马路玩手机或将罚款50元 你支持吗?
世界快看:东风概念飞行汽车外观曝光!“鸥翼门”相当炫酷
【当前热闻】2018巴彦淖尔国际马拉松
环球焦点!胡明轩:平时杜导叫我和徐杰一起训练 要求我们承担起更多责任
世界快讯:makefile
基于alpine基础镜像构建jdk镜像以及tomcat镜像及业务构建
Linux极简入门系列(六):其它补充
CSS全局关键字
环球聚焦:委员建议隔周三休成热搜第一 网友吵翻 专家:很难行得通
今日热闻!Model 2明天发?这款15万的特斯拉便宜车:马斯克已经说了17年
环球新消息丨LOJ 3276 JOISC 2020 Day2 遗迹 题解 (计数DP)
环球快资讯:MySQL学习笔记-多表查询(上)
当前视讯!量化交易基础 - 011 - 样本外检验
风语筑(603466):上海风语筑文化科技股份有限公司关于股东权益变动比例超过1%的提示性公告
天天观察:希望工程发文感谢《原神》玩家 5天9万多人捐赠240万元
世界聚焦:“刺客”又来了!网友称买到1600元一斤话梅:每颗至少20元
“窄边教科书”上新!戴尔XPS15 9530发布:13代酷睿+RTX 40配8TB SSD
环球微动态丨孟菲斯动物园发大熊猫丫丫新动态 网友:尽快回国!
曝苹果屏下Face ID技术有缺憾:2026年才会趋于完美
C++ STL学习笔记-C++ STL基础
焦点讯息:4-Ribbon负载均衡
信息:可取代eSIM:更完美的iSIM卡来了
二月浏览器大战结果出炉:微软Edge用户数不升反降
头条:《王者荣耀》干将莫邪画中仙皮肤公布:中国古风莫邪绝美
环球微头条丨k8s之list-watch机制、节点调度以及亲和性
全球速讯:记录--虚拟滚动探索与封装
天天百事通!(数据库系统概论|王珊)第七章数据库设计-第四节:逻辑结构设计
焦点热议:Cesium 几何体贴模型 sampleHeight(二十二)
环球滚动:苏富比春拍上海预展即将开展,近150件藏品由谁保驾护航?
全球即时看!蔚来2022年财报公布:全年营收492亿元 同比大涨36%
天天资讯:建议元宵节放假1天:提升人民幸福指数
环球通讯!超19万辆!比亚迪2月新能源销量公布:暴打新势力全家
全球微头条丨2023五一档电影增至五部!哪部对你吸引力更大?
热点!Cesium Transform(二十)
世界速讯:第124篇: 期约Promise