Linux中通过Socket文件描述符寻找连接状态介绍
针对下文的总结:socket是一种文件描述符
进程的打开文件描述符表
Linux的三个系统调用:open,socket,pipe 返回的都是一个描述符。不同的进程中,他们返回的描述符可以相同。那么,在同一个进程中,他们可以相同吗?或者说,普通文件、套接字和管道,这三者的描述符属于同一个集合吗?
在内核源码中,三个系统调用声明如下:
- SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode);
- SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol);
- SYSCALL_DEFINE1(pipe, int __user *, fildes);
他们都会先后调用函数
- get_unused_fd_flags:获取当前进程打开文件描述符表中的空闲描述符;
- fd_install:安装新描述符到当前进程打开文件描述符表。
内核为每个进程维护了一个结构体struct task_struct,可称为进程表项、进程控制块(PCB: Process Control Block)或者进程描述符,定义如下:
- struct task_struct {
- volatile long state; /* -1 unrunnable, 0 runnable,>0 stopped */
- …
- pid_t pid;
- …
- struct files_struct *files;
- …
- };
其中files成员成为打开文件描述符表,定义如下:
- struct files_struct {
- …
- struct fdtable fdtab;
- …
- struct file __rcu * fd_array[NR_OPEN_DEFAULT];
- };
其成员fdtab为关键数据成员,定义如下:
- struct fdtable {
- unsigned int max_fds;
- struct file __rcu **fd; /* current fd array */
- unsigned long *close_on_exec;
- unsigned long *open_fds;
- struct rcu_head rcu;
- };
这说明普通的文件、套接字、管道等,都被抽象为文件,共同占用进程的打开文件描述符。
http://blog.csdn.net/aprilweet/article/details/53482930
========================另外一篇=============================
/Proc 目录下面有许多数字命名的子目录,这些数字表示系统当前运行的进程号;
其中/proc/N/fd目录下面保存了打开的文件描述符,指向实际文件的一个链接。如下:
root@yang-ubuntu:/proc/4810/fd# ll
总用量 0
dr-x------ 2 root root 0 3月 8 16:07 ./
dr-xr-xr-x 8 root root 0 3月 8 16:07 ../
lrwx------ 1 root root 64 3月 8 16:08 0 -> /dev/pts/1
lrwx------ 1 root root 64 3月 8 16:08 1 -> /dev/pts/1
lrwx------ 1 root root 64 3月 8 16:09 10 -> socket:[21190]
lrwx------ 1 root root 64 3月 8 16:07 2 -> /dev/pts/1
lrwx------ 1 root root 64 3月 8 16:08 3 -> /tmp/ZCUDY7QsPB (deleted)
lrwx------ 1 root root 64 3月 8 16:08 4 -> /tmp/sess_0fpvhvcpftcme834e1l4beo2i6
lrwx------ 1 root root 64 3月 8 16:08 5 -> socket:[20625]
lrwx------ 1 root root 64 3月 8 16:08 6 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 3月 8 16:08 7 -> socket:[20626]
lrwx------ 1 root root 64 3月 8 16:08 8 -> socket:[20627]
lrwx------ 1 root root 64 3月 8 16:09 9 -> socket:[21189]
我们想查看],这个数字又是哪儿来的呢?请往下看。
在/proc/net/tcp目录下面保存了所有TCP链接的状态信息。
root@yang-ubuntu:/proc/net# vim /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:0CEA 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1001 0 9482 1 ffff88001a501a00 100 0 0 10 -1
1: 00000000:008B 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 8916 1 ffff88001a501380 100 0 0 10 -1
2: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11440 1 ffff88001a502080 100 0 0 10 -1
3: 0100007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12333 1 ffff88001a502700 100 0 0 10 -1
4: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7922 1 ffff88001a500000 100 0 0 10 -1
5: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13302 1 ffff88001a500680 100 0 0 10 -1
6: 00000000:01BD 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 8914 1 ffff88001a500d00 100 0 0 10 -1
7: 00000000:0929 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 20625 1 ffff88001a504100 100 0 0 10 -1
8: 8064A8C0:01BD 0164A8C0:C26A 01 00000000:00000000 02:00030E57 00000000 0 0 13216 2 ffff88001a503a80 22 4 1 10 18
2 ffff88001a505b00 24 4 28 10 -1
10: 8064A8C0:0016 0164A8C0:CD9C 01 00000000:00000000 02:0000B4B4 00000000 0 0 17721 2 ffff88001a503400 22 4 20 10 -1
11: 8064A8C0:0016 0164A8C0:CDAE 01 00000000:00000000 02:0000DB1B 00000000 0 0 18130 2 ffff88001a504e00 24 4 31 10 -1
12: 8064A8C0:0929 0164A8C0:F4B6 01 00000000:00000000 02:00097B3E 00000000 0 0 21190 2 ffff88001a506800 24 4 24 10 -1
13: 8064A8C0:0016 0164A8C0:CDAC 01 00000000:00000000 02:0000DB1B 00000000 0 0 18074 2 ffff88001a502d80 21 4 24 10 -1
14: 8064A8C0:0016 0164A8C0:F3FC 01 00000000:00000000 02:00089B3B 00000000 0 0 20675 2 ffff88001a506180 24 4 25 10 -1
15: 8064A8C0:0016 0164A8C0:CDAD 01 00000080:00000000 01:00000018 00000000 0 0 18102 4 ffff88001a504780 24 4 21 10 -1
看上数字【21189 】没有,就是这儿来的,到此我们可以找出链接的IP、PORT链接四元组【8064A8C0:0929 0164A8C0:F4B5】这个地方是用十六进制保存的,换算成十进制方式【192.168.100.128:2345 192.168.100.1:62645】;
去网络连接状态里面看一下:
root@yang-ubuntu:/proc/4275/fd# netstat -antp
激活Internet连接 (服务器和已建立连接的)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1710/mysqld
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN 1062/smbd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1736/nginx.conf
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1925/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 628/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 709/cupsd
tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN 1062/smbd
tcp 0 0 0.0.0.0:2345 0.0.0.0:* LISTEN 4809/start.php
tcp 0 0 192.168.100.128:445 192.168.100.1:49770 ESTABLISHED 2514/smbd
tcp 0 0 192.168.100.128:2345 192.168.100.1:62645 ESTABLISHED 4810/0.0.0.0:2345
tcp 0 0 192.168.100.128:22 192.168.100.1:52636 ESTABLISHED 3565/sshd: root@not
tcp 0 0 192.168.100.128:22 192.168.100.1:52654 ESTABLISHED 3718/3
tcp 0 0 192.168.100.128:22 192.168.100.1:52652 ESTABLISHED 3714/1
tcp 0 0 192.168.100.128:22 192.168.100.1:62460 ESTABLISHED 4817/4
tcp 0 0 192.168.100.128:22 192.168.100.1:52653 ESTABLISHED 3716/2
tcp6 0 0 :::139 :::* LISTEN 1062/smbd
tcp6 0 0 :::22 :::* LISTEN 628/sshd
tcp6 0 0 ::1:631 :::* LISTEN 709/cupsd
tcp6 0 0 :::445 :::* LISTEN 1062/smbd
回到开始的问题:9 Socket文件描述符代表的是本地【192.168.100.128:2345】到【192.168.100.1:62645】的一条TCP连接!
为什么往socket中写数据,就会发送到对端(只针对tcp协议的研究)? 举例:浏览器请求服务器?
客户端首先发起建立与服务器TCP连接。一旦建立连接,浏览器进程和服务器进程就可以通过各自的套接字来访问TCP。
客户端套接字是客户进程和TCP连接之间的“门”,服务器端套接字是服务器进程和同一TCP连接之间的“门”。
客户往自己的套接字发送HTTP请求消息,也从自己的套接字接收HTTP响应消息。
类似地,服务器从自己的套接字接收HTTP请求消息,也往自己的套接字发送HTTP响应消息。
客户端或服务器一旦把某个消息送入各自的套接字,这个消息就完全落入TCP的控制之中。//所以说底层是基于tcp提供的可靠的消息传输机制
TCP给HTTP提供一个可靠的数据传输服务;这意味着由客户发出的每个HTTP请求消息最终将无损地到达服务器,由服务器发出的每个HTTP响应消息最终也将无损地到达客户。
Linux中通过Socket文件描述符寻找连接状态介绍的更多相关文章
- 自学Linux Shell14.2-在脚本中使用其他文件描述符
点击返回 自学Linux命令行与Shell脚本之路 14.2-在脚本中使用其他文件描述符 在脚本中重定向输入和输出,并布局限于以上讲的3个默认的文件描述符,shell最多可以有9个打开的文件描述符.这 ...
- linux专题一之文件描述符、重定向、管道符、tee命令
本节讨论一下几个问题: 1. 文件描述符. 2. 重定向. 3. 管道符 4. tee的用法. 1. 文件描述符. 在linux系统中一切皆文件.文件夹和设备都是文件.如何用来区别不同的文件呢?这里的 ...
- Linux 进程间传递文件描述符
文章目录 文件描述符 文件数据结构 共享文件 UNIX域socket实现传递文件描述符 进程间传递打开的文件描述符,并不是传递文件描述符的值.先说一下文件描述符. 文件描述符 对内核来说,所有打开的文 ...
- [转] linux系统文件流、文件描述符与进程间关系详解
http://blog.sina.com.cn/s/blog_67b74aea01018ycx.html linux(unix)进程与文件的关系错综复杂,本教程试图详细的阐述这个问题. 包括: ...
- linux最大允许的文件描述符open files数nofile修改
open file resource limit 是linux中process可以打开的文件句柄数量.增加这个数值需要调整两个配置: 第一步, 修改系统最大允许的文件描述符 查看当前的设置: $ ca ...
- linux shell exec 关联文件描述符
在写shell脚本时,如果多个命令的输入或输出都是同一个文件,而这个文件的路径和名字都很长,则需要书写很多次同样的路径会很浪费时间,我们可以使用exec命令来关联一个自定义的文件描述符到一个特定的文件 ...
- Linux最大文件句柄(文件描述符)限制和修改
转自:http://jameswxx.iteye.com/blog/2096461 写这个文章是为了以正视听,网上的文章人云亦云到简直令人发指.到底最大文件数被什么限制了?too many open ...
- linux修改最大的文件描述符(max file descriptors)
用xshell登录linux系统之后,用命令>ulimit -a 注意到系统模式是1024个 使用>ulimit -n 数量,可临时更改,生效范围为当前会话 永久修改的方法: > v ...
- Linux中的文件描述符与打开文件之间的关系
Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...
随机推荐
- return & finally 执行顺序 这是我读到的最合理的解释
新词:return [expression] 栈顶元素 局部变量的快照 java方法是在栈幀中执行,栈幀是线程私有栈的单位,执行方法的线程会为每一个方法分配一小块栈空间来作为该方法执行时的内存空间, ...
- ifcfg命令
ifcfg命令是一个bash脚本程序,用来设置Linux中的网络接口参数. 语法 ifcfg(参数) 参数 网络接口:指定要操作的网络接口: add/del:添加或删除网络接口上的地址: ip地址:指 ...
- Xcode工程编译错误之iOS开发之Xcode9报错 Compiling IB documents for earlier than iOS7 is no longer supported.
概要: 在我们升级到Xcode9时,最低的编译版本为iOS8,但是在使用一些SDK的时候就会报出Compiling IB documents for earlier than iOS7 is no l ...
- 获取子字符串函数MidStr
MidStr返回指定范围内的字符串.该函数有三个参数.第一个参数为源字符串,第二个参数为起点(下标从1开始),第三个参数为结束点.通过第二.第三个参数则可指定要复制字符串的范围. function M ...
- ts-loader 安装问题
首先,有个问题:ts-loader是将typescript转成javascript,转成哪个版本的javascript版本? 查询到参考地址:http://morning.work/page/othe ...
- Redis的数据结构之List
存储list: ArrayList使用数组方式 LinkedList使用双向链接方式 双向链接表中增加数据 双向链接表中删除数据 存储list常用命令 两端添加 两端弹出 扩展命令 lpush 方式添 ...
- Jedis简介
实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: https://redis.io/clients https://redi ...
- numactl 修改 非统一内存访问架构 NUMA(Non Uniform Memory Access Architecture)模式
当今数据计算领域的主要应用程序和模型可大致分为三大类: (1)联机事务处理(OLTP). (2)决策支持系统(DSS) (3)企业信息通讯(BusinessCommunications) 上述三类系统 ...
- ORA-00444: background process DBRM failed while starting
SQL> startup 报错:ORA-00444: background process DBRM failed while startingORA-00020:maximum number ...
- Pycharm激活方法步骤
Pycharm激活步骤 第一步:找到hosts文件 先按下键盘的win + r ,然后复制c:\windows\system32\drivers\etc粘贴到对话框回车打开文件管理器 第二步:修改ho ...