当前位置:首页 > 公众号精选 > CPP开发者
[导读]socketfd长什么样子?什么是socketfd?粗糙的来讲,就是网络fd,比如我们最常见的C/S客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别,不就是读过来和写过去嘛,简称IO。我们先看一下socket...



socket fd 长什么样子?


什么是 socket fd ?粗糙的来讲,就是网络 fd,比如我们最常见的 C/S 客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信文件读写从接口上有本质区别吗?

其实没啥区别,不就是读过来和写过去嘛,简称 IO 。

我们先看一下 socket fd 是什么样子的?随便找了个进程

root@ubuntu:~# ll /proc/1583/fd
total 0
lrwx------ 1 root root 64 Jul 19 12:37 7 -> socket:[18892]
lrwx------ 1 root root 64 Jul 19 12:37 8 -> socket:[18893]
这里我们看到 fd 7、8 都是一个 socket fd,名字:socket:[18892]

整数句柄后面一般会跟一些信息,用于帮助我们了解这个 fd 是什么。举个例子,如果是文件 fd,那么箭头后面一般是路径名称。现在拆解一下这个名字:

  • socket :标识这是一个 socket 类型的 fd
  • [18892]  :这个是一个 inode 号,能够唯一标识本机的一条网络连接;
思考下,这个 inode 号,还能再哪里能看到呢?

在 proc 的 net 目录下,因为我这个是一个走 tcp 的服务端,所以我们看一下  /proc/net/tcp 文件。这个文件里面能看到所有的 tcp 连接的信息。

root@ubuntu:~# grep -i "18892" /proc/net/tcp
  18: 00000000:1F93 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 18892 1 ffff880197fba580 100 0 0 10 0                     
root@ubuntu:~# grep -i "18893" /proc/net/tcp
  28: 00000000:1F7C 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 18893 1 ffff880197fbad00 100 0 0 10 0    
知识点又来了,/proc/net/tcp 这个文件记录了 tcp 连接的信息,这份信息是非常有用的。包含了 TCP 连接的地址(16进制显示),inode 的信息,连接的状态等等。


socket fd 是什么?


环境声明

Linux 内核版本 4.19 

为了方便,如果没特意说明协议,默认 TCP 协议;

socket 可能你还没反应过来,中文名:套接字 是不是更熟悉点。Linux 网络编程甚至可以叫做套接字编程。

有些概念你必须捋一捋 。我们思考几个小问题:

socket 跟 tcp/ip 有什么区别?

就不该把这两个东西放在一起比较讨论,就不是一个东西。tcp/ip 是网络协议栈,socket 是操作系统为了方便网络编程而设计出来的编程接口而已。

理论基础是各种网络协议,协议栈呀,啥的。但是如果你要进行网络编程,落到实处,对程序猿来讲就是 socket 编程。

对于网络的操作,由 socket 体现为 open -> read/write ->close 这样的编程模式,这个统一到文件的一种形式。

socket 的 open 就是 socket(int domain, int type, int protocol) ,和文件一样,都是获取一个句柄。


网络抽象层次


网络模型一般会对应到两种:

  • 完美理论的 OSI 七层模型
  • 现实应用的 5 层模型;
对应关系如下图(取自 Unix 套接字编程)



不同层次做不同的事情,不断的封装,不断的站在巨人的肩膀上,你将能做的更多。



今天,奇伢剖析的只聚焦在套接字这一层,这是程序猿摸得到的一层,位于所有网络协议之上的一层封装,网络编程又叫套接字编程,这并不是空穴来风。

套接字,是内核对贼复杂的网络协议栈的 API 封装,使得程序猿能够用极简的姿势进行网络编程。比如写一个基于 Tcp 的 C/S 的网络程序,需要用到啥?我们大概畅想下:

  1. 客户端和服务端都用 socket 调用创建套接字;
  2. 服务端用 bind 绑定监听地址,用 listen 把套接字转化为监听套接字,用 accept 捞取一个客户端来的连接;
  3. 客户端用 connect 进行建连,用 write/read 进行网络 IO;
程序猿用着好简单!因为内核把事扛了。


socket fd 的类型


上面我们提到了套接字,这是我们网络编程的主体,套接字由 socket() 系统调用创建,但你可知套接字其实可分为两种类型,监听套接字和普通套接字。而监听套接字是由 listen() 把 socket fd 转化而成。


 1   监听套接字

对于监听套接字,不走数据流,只管理连接的建立。accept 将从全连接队列获取一个创建好的 socket( 3 次握手完成),对于监听套接字的可读事件就是全连接队列非空。对于监听套接字,我们只在乎可读事件。


 2   普通套接字

普通套接字就是走数据流的,也就是网络 IO,针对普通套接字我们关注可读可写事件。在说 socket 的可读可写事件之前,我们先捋顺套接字的读写大概是什么样子吧。

套接字层是内核提供给程序员用来网络编程的,程序猿读写都是针对套接字而言,那么 write( socketfd, /* 参数 */)read( socketfd, /* 参数 */) 都会发生什么呢?

  • write 数据到 socketfd,大部分情况下,数据写到 socket 的内存 buffer,就结束了,并没有发送到对端网络(异步发送);
  • read socketfd 的数据,也只是从 socket 的 内存 buffer 里读数据而已,而不是从网卡读(虽然数据是从网卡一层层递上来的);
也就是说,程序猿而言,是跟 socket 打交道,内核屏蔽了底层的细节。

那说回来 socket 的可读可写事件就很容易理解了。

  • socketfd 可读:其实就是 socket buffer 内有数据(超过阈值 SO_RCLOWAT );
  • socketfd 可写:就是 socket buffer 还有空间让你写(阈值 SO_SNDLOWAT );


sockfs 文件系统


socket fd 为什么能具备“文件”的语义,从而和 eventfd,ext2 fd 这样的句柄一样,统一提供对外 io 的样子?

核心就是:sockfs ,这也是个文件系统,只不过普通用户看不见,这是只由内核管理的文件系统,位于 vfs 之下,为了封装 socket 对上的文件语义。

// net/socket.c
static int __init sock_init(void)
{
    // 注册 sockfs 文件系统
    err = register_filesystem(
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在进行socket通信开发时,一般会用到TCP或UDP这两种传输层协议,UDP(User Datagram Protocol)是一种面向无连接的协议,在数据发送前,不需要提前建立连接,它可以更高效地传输数据,但可靠性无法...

关键字: socket TCP UDP

相关阅读:《eBPF技术应用云原生网络实践系列之kubernetes网络》背景介绍Kubernetes中的网络功能,主要包括POD网络,service网络和网络策略组成。其中POD网络和网络策略,都是规定了模型,没有提供...

关键字: service socket

相关阅读:《eBPF技术应用云原生网络实践系列之kubernetes网络》背景介绍Kubernetes中的网络功能,主要包括POD网络,service网络和网络策略组成。其中POD网络和网络策略,都是规定了模型,没有提供...

关键字: service socket

socketfd长什么样子?什么是socketfd?粗糙的来讲,就是网络fd,比如我们最常见的C/S客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别...

关键字: socket

socketfd长什么样子?什么是socketfd?粗糙的来讲,就是网络fd,比如我们最常见的C/S客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别...

关键字: socket

socketfd长什么样子?什么是socketfd?粗糙的来讲,就是网络fd,比如我们最常见的C/S客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别...

关键字: socket

socketfd长什么样子?什么是socketfd?粗糙的来讲,就是网络fd,比如我们最常见的C/S客户端服务端的编程模式,就是网络通信的一种方式。撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别...

关键字: socket

     UDP简介   UDP: User Datagram Protocol的简称, 中文名是用户数据包协议,是 OSI 参考模型中一种无连接的传输层协

关键字: socket udp

  socket是什么   从编程语言的角度,socket是一个无符号整型变量,用来标识一个通信进程。两个进程通信,总要知道这几个信息:双方的ip地址和端口号,通信所采用的协议栈。soc

关键字: socket

  Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相

关键字: socket
关闭
关闭