ss 查看SOCKET使用情况

1、命令格式:
ss [参数]
ss [参数] [过滤]
2、命令功能:
ss(Socket Statistics的缩写)命令可以用来获取 socket统计信息,此命令输出的结果类似于
netstat输出的内容,但它能显示更多更详细的 TCP连接状态的信息,且比 netstat 更快速高效。它使用了 TCP协议栈中
tcp_diag(是一个用于分析统计的模块),能直接从获得第一手内核信息,这就使得 ss命令快捷高效。在没有
tcp_diag,ss也可以正常运行。
3、命令参数:
-h, –help 帮助信息
-V, –version 程序版本信息
-n, –numeric 不解析服务名称
-r, –resolve 解析主机名
-a, –all 显示所有套接字(sockets)
-l, –listening 显示监听状态的套接字(sockets)
-o, –options 显示计时器信息
-e, –extended 显示详细的套接字(sockets)信息
-m, –memory 显示套接字(socket)的内存使用情况
-p, –processes 显示使用套接字(socket)的进程
-i, –info 显示 TCP内部信息
-s, –summary 显示套接字(socket)使用概况
-4, –ipv4 仅显示IPv4的套接字(sockets)
-6, –ipv6 仅显示IPv6的套接字(sockets)
-0, –packet 显示 PACKET 套接字(socket)
-t, –tcp 仅显示 TCP套接字(sockets)
-u, –udp 仅显示 UCP套接字(sockets)
-d, –dccp 仅显示 DCCP套接字(sockets)
-w, –raw 仅显示 RAW套接字(sockets)
-x, –unix 仅显示 Unix套接字(sockets)
-f, –family=FAMILY 显示 FAMILY类型的套接字(sockets),FAMILY可选,支持 unix, inet, inet6, link, netlink
-A, –query=QUERY, –socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D, –diag=FILE 将原始TCP套接字(sockets)信息转储到文件
-F, –filter=FILE 从文件中都去过滤器信息
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
4、使用实例:



ss -s


Total: 140 (kernel 166)
TCP: 108 (estab 84, closed 16, orphaned 0, synrecv 0, timewait 15/0), ports 88



Transport Total IP IPv6



  • 166 - -
    RAW 0 0 0
    UDP 0 0 0
    TCP 92 92 0
    INET 92 92 0
    FRAG 0 0 0



ss -t -a


State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :http *:
SYN-RECV 0 0 10.0.0.2:http 5.206.224.30:optika-emedia
LISTEN 0 128 :epmd *:
LISTEN 0 128 :ssh *:
LISTEN 0 128 :15672 *:
LISTEN 0 128 :https *:
LISTEN 0 128 :amqp *:
LISTEN 0 128 :25672 *:
ESTAB 0 0 10.0.0.2:46408 10.0.0.7:27017
TIME-WAIT 0 0 127.0.0.1:47209 127.0.0.1:http
TIME-WAIT 0 0 10.0.0.2:56428 17.143.163.8:2195
ESTAB 0 0 10.0.0.2:33258 10.0.0.8:27017



也可以直接查看sockstat



cat /proc/net/sockstat


sockets: used 141
TCP: inuse 93 orphan 0 tw 13 alloc 94 mem 19
UDP: inuse 0 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0



说明:
sockets: used:已使用的所有协议套接字总量
TCP: inuse:正在使用(正在侦听)的TCP套接字数量。其值≤ netstat –lnt | grep ^tcp | wc –l
TCP: orphan:无主(不属于任何进程)的TCP连接数(无用、待销毁的TCP socket数)
TCP: tw:等待关闭的TCP连接数。其值等于netstat –ant | grep TIME_WAIT | wc –l
TCP:alloc(allocated):已分配(已建立、已申请到sk_buff)的TCP套接字数量。其值等于netstat –ant | grep ^tcp | wc –l
TCP:mem:套接字缓冲区使用量(单位不详。用scp实测,速度在4803.9kB/s时:其值=11,netstat –ant 中相应的22端口的Recv-Q=0,Send-Q≈400)
UDP:inuse:正在使用的UDP套接字数量
RAW:
FRAG:使用的IP段数量



IPv6请看:cat /proc/net/sockstat6

https://blog.csdn.net/farmwang/article/details/78995372



1.netstat



nestat的使用方法没什么好说的,运维的家常必备,如果连这个都不会那是相当不靠谱



[root@localhost ]# netstat -n



Active Internet connections (w/o servers)



Proto Recv-Q Send-Q Local Address Foreign Address State



tcp 0 0 192.168.22.240:55197 192.168.22.238:81 TIME_WAIT



tcp 0 0 192.168.22.240:22 192.168.22.76:52426 ESTABLISHED



tcp 0 0 192.168.22.240:55229 192.168.22.238:81 TIME_WAIT



tcp 0 0 192.168.22.240:39833 192.168.22.238:81 TIME_WAIT



----- 略-------------



如果系统连接数很多、负载飚高,使用netstat命令可能会半天出不了结果,这个时候下面的2个方法就派上用场了。




  1. ss



通过ss命令可以获取系统的所有TCP/UDP sockets使用情况以及已经建立的ssh/ftp/http等连接情况。



//显示系统的socket汇总信息



[root@localhost ]# ss -s



Total: 318 (kernel 467)



TCP: 327 (estab 101, closed 189, orphaned 7, synrecv 0, timewait 185/0), ports 245



Transport Total IP IPv6




  • 467 - -



RAW 1 1 0



UDP 6 5 1



TCP 138 92 46



INET 145 98 47



FRAG 0 0 0



//显示运行的进程及其使用的端口



[root@localhost ]# ss -pl



//显示所有TCP/UDP信息



[root@localhost ]# ss -t/-u -a



//显示所有状态为established的http连接



[root@localhost examples]# ss -o state established ‘( dport = :http or sport = :http )’



ecv-Q Send-Q Local Address:Port Peer Address:Port



82 0 ::ffff:192.168.22.240:http ::ffff:192.168.22.238:41934 timer:(keepalive,120min,0)



82 0 ::ffff:192.168.22.240:http ::ffff:192.168.22.238:41933 timer:(keepalive,119min,0)



0 0 ::ffff:192.168.22.240:http



TCP的状态不少,可以根据自已的需要过滤



established



syn-sent



syn-recv



fin-wait-1



fin-wait-2



time-wait



closed



close-wait



last-ack



listen



closing



all : All of the above states



connected : All the states except for listen and closed



synchronized : All the connected states except for syn-sent



bucket : Show states, which are maintained as minisockets, i.e. time-wait and syn-recv.



big : Opposite to bucket state.



示例就列这些吧,更详细的用法可以 man ss



3./proc/net/socketstat



[root@localhost ]#cat /proc/net/sockstat



sockets: used 137



TCP: inuse 49 orphan 0 tw 3272 alloc 52 mem 46



UDP: inuse 1 mem 0



RAW: inuse 0



FRAG: inuse 0 memory 0



说明:



sockets: used:已使用的所有协议套接字总量











TCP: inuse:正在使用(正在侦听)的TCP套接字数量。其值≤ netstat –lnt grep ^tcp wc –l


TCP: orphan:无主(不属于任何进程)的TCP连接数(无用、待销毁的TCP socket数)











TCP: tw:等待关闭的TCP连接数。其值等于netstat –ant grep TIME_WAIT wc –l










TCP:alloc(allocated):已分配(已建立、已申请到sk_buff)的TCP套接字数量。其值等于netstat –ant grep ^tcp wc –l


TCP:mem:套接字缓冲区使用量(单位不详。用scp实测,速度在4803.9kB/s时:其值=11,netstat –ant 中相应的22端口的Recv-Q=0,Send-Q≈400)



UDP:inuse:正在使用的UDP套接字数量



RAW:



FRAG:使用的IP段数量



http://blog.chinaunix.net/uid-10480699-id-5179854.html











ls /proc/18709/fd -l grep socket: wc -l 18709是进程ID









可以通过 ps aux grep 进程名称 来获取到


https://www.cnblogs.com/tomato0906/articles/9657419.html



1、修改用户进程可打开文件数限制
在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。
对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。
修改上述限制的最简单的办法就是使用ulimit命令:
[speng@as4 ~]$ ulimit -n
上述命令中,在中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。
第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
speng soft nofile 10240
speng hard nofile 10240
其中speng指定了要修改哪个用户的打开文件数限制,可用’*‘号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后保存此文件。
第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
echo 22158 > /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。
完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit -n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
2、修改网络内核对TCP连接的有关限制(参考对比下篇文章“优化内核参数”)
在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。
第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
static int tcp_v4_hash_connect(struct sock *sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
void __init tcp_init(void)
内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range = 1024 65000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。
第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max = 10240
这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。
3、使用支持高并发网络I/O的编程技术
在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步 I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。



内核参数sysctl.conf的优化



/etc/sysctl.conf 是用来控制linux网络的配置文件,对于依赖网络的程序(如web服务器和cache服务器)非常重要,RHEL默认提供的最好调整。



推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):
net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2



这个配置参考于cache服务器varnish的推荐配置和SunOne 服务器系统优化的推荐配置。



varnish调优推荐配置的地址为:http://varnish.projects.linpro.no/wiki/Performance



不过varnish推荐的配置是有问题的,实际运行表明“net.ipv4.tcp_fin_timeout = 3”的配置会导致页面经常打不开;并且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页都会打不开,重启浏览器后正常。可能是国外的网速快吧,我们国情决定需要调整“net.ipv4.tcp_fin_timeout = 10”,在10s的情况下,一切正常(实际运行结论)。



修改完毕后,执行:
/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1



命令生效。为了保险起见,也可以reboot系统。



调整文件数:
linux系统优化完网络必须调高系统允许打开的文件数才能支持大的并发,默认1024是远远不够的。



执行命令:
Shell代码
echo ulimit -HSn 65536 » /etc/rc.local
echo ulimit -HSn 65536 »/root/.bash_profile
ulimit -HSn 65536



https://www.cnblogs.com/lidabo/p/6042021.html



怎么查看 当前进程 的Socket 连接数?
tcpview,netstat -nao



首先我们可以通过ulimit –a命令来查看系统的一些资源限制情况,如下:



ulimit -acore file size (blocks, -c) 1024data seg size (kbytes, -d) unlimitedscheduling priority (-e) 0file size (blocks, -f) unlimitedpending signals (-i) 127422max locked memory (kbytes, -l) 64max memory size (kbytes, -m) unlimitedopen files (-n) 20480pipe size (512 bytes, -p) 8POSIX message queues (bytes, -q) 819200real-time priority (-r) 0stack size (kbytes, -s) unlimitedcpu time (seconds, -t) unlimitedmax user processes (-u) 81920virtual memory (kbytes, -v) unlimitedfile locks (-x) unlimited


这里重点关注open files和max user processes。分别表示:单个进程打开的最大文件数;系统可以申请最大的进程数。



1、查看、修改文件数(当前session有效):



ulimit -n20480# ulimit -n 20480


2、查看、修改进程数(当前session有效):



ulimit -u81920# ulimit -u 81920


3、永久设置文件数、最大进程:



可以编辑# vim /etc/security/limits.conf在其中指定最大设置; 或者在/etc/profile文件指定;
一、最大进程数:



最近在Linux服务器上发布应用时碰到一个如下的异常:



Caused by: java.lang.OutOfMemoryError: unable to create new native threadat java.lang.Thread.start0(Native Method)at java.lang.Thread.start(Thread.java:640)
初看可能会认为是系统的内存不足,如果这样想的话就被这段提示带到沟里面去了。上面这段错误提示的本质是Linux操作系统无法创建更多进程,导致出错。因此要解决这个问题需要修改Linux允许创建更多的进程。



1、临时设置:



我们可以使用 ulimit -u 81920 修改max user processes的值,但是只能在当前终端的这个session里面生效,重新登录后仍然是使用系统默认值。



2、永久设置:



1)编辑# vim /etc/security/limits.conf



在文件中添加如下内容:



soft nproc 81920 hard nproc 81920
注: *表示所有用户,soft、hard表示软限制、硬限制。(软限制<=硬限制)



2)或者在/etc/profile文件中添加:



ulimit -u 81920
这样每次用户登录就可以设置最大进程数。



二、最大打开文件数:



最大文件打开数在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。



1、查看最大打开文件数:



$ ulimit -n1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。



https://www.ctolib.com/topics-99415.html



Unix域协议是在单个主机上执行客户/服务器通信的一种方法,用在本地进程间的通信,在不同进程之间传递套接字。



1)Unix域套接字不需要打包/拆包,计算校验和维护序号与应答,只是将应用层数据从一个进程拷贝到另一个进程,而且Unix域协议机制本质上就是可靠的通讯。



2)Unix套接字可以在同一台主机上各进程之间传递文件描述符。



3)Unix域协议表示协议地址的是路径名,而不是Internet域的IP地址和端口号



 



需注意:





  1. bind()成功将会创建一个文件,是一个套接字类型




  2. sun_path 最好用一个/tmp目录下的文件的绝对路径,再次启动时最好使用unlink删除这个文件,否则会提示地址正在使用。




  3. Unix域协议支持流式套接口与报式套接口




  4. Unix域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED




  5. 流式套接字需要处理粘包问题。





 



Unix SocketStructure



Sockaddr /sockaddr_in / in_addr / hostent / servent /



客户端通过connect()函数与服务器连接



在一个单处理器计算机上,同一时间只能有一个进程可以运行,其他进程处于等待运行状态。每个进程轮到的运行时间(时间片)相当短暂,给人一种多个程序在同时运行的假象。



 



编写多线程程序时,通过定义宏_REENTRANT来告诉编译器我们需要可重入功能,这个定义必须位于程序中任何#include之前。



Pthread_create创建一个新线程,调用成功时返回0,否则返回错误代码;



线程通过调用pthread_exit()终止调用它的线程并返回一个指向某个对象的指针,注意不能返回局部变量的指针,以免引起严重的程序漏洞。



当从一个进程连接数据流到另一个进程时—管道。把一个进程的输出通过管道连接到另一个进程的输入。



Pipe()参数是一个由两个整数类型的文件描述符组成的数组的指针,数据基于先进先出(FIFO)的原则。从File_descriptor[1]向管道中写数据,再从File_descriptor[0]读回数据。管道有一些内置的缓存区,它在write和read调用之间保存数据。



命名管道(named pipe)



首先服务器应用程序用系统调用socket来创建一个套接字,它是系统分配给该服务器进程的类似文件描述符的资源,不能与其他进程共享。



接下来,服务器进程会给套接字起个名字,本地套接字的名字是Linux系统中的文件名,一般放在/tmp目录中。系统调用bind()来给套接字命名,然后服务器进程就开始等待客户连接到这个命名套接字。系统调用listen创建一个队列并将其用于存放来自客户的进入连接。服务器通过系统调用accept来接受客户的连接。



服务器调用accept时会创建一个与原有的命名套接字不同的新套接字,这个新套接字只用于与这个特定客户进行通信,而命名套接字则被保留下来继续处理来自其他客户的连接。



基于套接字系统的客户端更加简单,客户首先调用accept创建一个未命名套接字,然后将服务器的命名套接字作为一个地址来调用connect与服务器建立连接。一旦连接建立,就可以像使用底层的文件描述符那样用套接字来实现双向的数据通信。



套接字特性由3个属性确定,域(domain)、类型(type)和协议(protocol)



套接字的域指定套接字通信中使用的网络介质,AF_INET指的是Internet网络,许多Linux局域网使用的均是该网络,其底层协议-网络协议(IP)只有一个地址族,它使用一种特定的方式来指定网络中的计算机(IP地址)点分四元组表示法(dotted quad),当客户使用套接字进行跨网络的连接时,它就需要用到服务器计算机的IP地址。客户可以通过IP端口来指定一台联网机器上的某个特定服务。套接字作为通信的终点,必须在开始通信之前绑定一个端口。



服务器在特定的端口等待客户的连接。



AF_UNIX即使是一台还未联网的计算机上的套接字也可以使用这个域,底层协议就是文件输入\输出,地址就是文件名。



套接字类型:流(stream)和数据报(datagram)



流套接字:提供一个有序、可靠、双向字节流的连接。大的数据被分片、传输再重组。接收大量的数据,然后以小数据块的形式将它们写入底层磁盘。发送的数据可以确保不会丢失、复制或乱序到达,并且在这一过程中发生的错误也不会显示出来。SOCK_STREAM



数据报套接字:SOCK_DGRAM 不建立和维持一个连接,对可以发送的数据报和数据报的长度有限制。数据报作为一个单独的网络消息被传输,可能会丢失、复制或乱序到达。从资源角度来看,开销相对较小,因为不需要维持网络连接,而且因为无需花费时间来建立连接,速度比较快。



要想让通过socket调用创建的套接字可以被其他进程使用,服务器程序就必须给该套接字命名。为了能够在套接字上接受进入的连接,服务器程序必须创建一个队列来保存未处理的请求。一旦服务器程序创建并命名了套接字后,它就可以通过accept系统调用来等待客户建立时对该套接字的连接。Accept只有当有客户程序试图连接到由socket参数指定的套接字上时才返回。客户指在套接字队列中排在第一个的未处理连接。Accept将创建一个新的套接字来与该用户进行通信,并且返回该新套接字的描述符。如果套接字队列中没有未处理的连接,accept将阻塞直到有客户建立连接为止。



客户程序通过一个未命名套接字和服务器监听套接字之间建立连接的方法连接服务器connect.



可以通过调用close函数来终止服务器和客户上的套接字连接



https://blog.csdn.net/huoyun7230/article/details/75839013



10.列出所有UNIX域Socket文件



# lsof -U



用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。



原理介绍
  在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。



语法
lsof (选项)
选项
-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。
实例
例1、lsof 不带任何参数运行lsof会列出所有进程打开的所有文件。



lsof输出各列信息的意义如下:



COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组
FD:文件描述符,应用程序通过文件描述符识别该文件。



文件描述符列表:



cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
lnn:library references (AIX);
er:FD information error (see NAME column);
jld:jail directory (FreeBSD);
ltx:shared library text (code and data);
mxx :hex memory-mapped type number xx.
m86:DOS Merge mapped file;
mem:memory-mapped file;
mmap:memory-mapped device;
pd:parent directory;
rtd:root directory;
tr:kernel trace file (OpenBSD);
v86 VP/ix mapped file;
0:表示标准输出
1:表示标准输入
2:表示标准错误



一般在标准输出、标准错误、标准输入后还跟着文件状态模式:



u:表示该文件被打开并处于读取/写入模式。
r:表示该文件被打开并处于只读模式。
w:表示该文件被打开并处于。
空格:表示该文件的状态模式为unknow,且没有锁定。
-:表示该文件的状态模式为unknow,且被锁定。



同时在文件状态模式后面,还跟着相关的锁:
N:for a Solaris NFS lock of unknown type;
r:for read lock on part of the file;
R:for a read lock on the entire file;
w:for a write lock on part of the file;(文件的部分写锁)
W:for a write lock on the entire file;(整个文件的写锁)
u:for a read and write lock of any length;
U:for a lock of unknown type;
x:for an SCO OpenServer Xenix lock on part of the file;
X:for an SCO OpenServer Xenix lock on the entire file;
space:if there is no lock.



文件类型:



DIR:表示目录。
CHR:表示字符类型。
BLK:块设备类型。
UNIX: UNIX 域套接字。
FIFO:先进先出 (FIFO) 队列。
IPv4:网际协议 (IP) 套接字。
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称



常用总结



  1. 找出谁在使用某个文件



# lsof /path/to/file



只需要执行文件的路径,lsof就会列出所有使用这个文件的进程,你也可以列出多个文件,lsof会列出所有使用这些文件的进程。



你也可以一次制定多个文件:



# lsof /path/to/file1 /path/to/file2



  1. 递归查找某个目录中所有打开的文件



# lsof +D /usr/bin



加上+D参数,lsof会对指定目录进行递归查找,注意这个参数要比grep版本慢:



# lsof | grep ‘/usr/lib’
之所以慢是因为+D首先查找所有的文件,然后一次性输出。



3.列出某个用户打开的所有文件



# lsof -u pkrumins
-u选项限定只列出所有被用户pkrumins打开的文件,你可以通过逗号指定多个用户:



# lsof -u rms,root
这条命令会列出所有rms和root用户打开的文件。



你也可以像下面这样使用多个-u做同样的事情:



# lsof -u rms -u root
4.查找某个程序打开的所有文件



# lsof -c apache



-c选项限定只列出以apache开头的进程打开的文件:



所以你可以不用像下面这样写:



# lsof | grep foo
而使用下面这个更简短的版本:



# lsof -c foo
事实上,你可以只制定进程名称的开头:



# lsof -c apa
这会列出所有以apa开头的进程打开的文件



你同样可以制定多个-c参数:



# lsof -c apache -c python
这会列出所有由apache和python打开的文件



5.列出所有由某个用户或某个进程打开的文件(组合)



lsof -u pkrumins -c apache


你也可以组合使用多个选项,这些选项默认进行或关联,也就是说上面的命令会输入由pkrumins用户或是apache进程打开的文件。



列出所有由一个用户-a选项表示 与某个进程打开的文件



lsof -a -u pkrumins -c bash



-a参数可以将多个选项的组合条件由或变为与,上面的命令会显示所有由pkrumins用户以及bash进程打开的文件。



列出除root用户外的所有用户打开的文件



lsof -u ^root


注意root前面的^符号,它执行取反操作,因此lsof会列出所有root用户之外的用户打开的文件。



6.列出所有由某个PID对应的进程打开的文件



# lsof -p 1
-p选项让你可以使用进程id来过滤输出。



记住你也可以用都好来分离多个pid。



# lsof -p 450,980,333
列出所有进程打开的文件除了某个pid的



# lsof -p ^1
同前面的用户一样,你也可以对-p选项使用^来进行取反。



7.列出所有网络连接



# lsof -i



lsof的-i选项可以列出所有打开了网络套接字(TCP和UDP)的进程。



列出所有TCP网络连接



# lsof -i tcp
也可以为-i选项加上参数,比如tcp,tcp选项会强制lsof只列出打开TCP sockets的进程。



列出所有UDP网络连接



# lsof -i udp
同样udp让lsof只列出使用UDP socket的进程。



找到使用某个端口的进程



# lsof -i :25
:25和-i选项组合可以让lsof列出占用TCP或UDP的25端口的进程。



你也可以使用/etc/services中制定的端口名称来代替端口号,比如:



# lsof -i :smtp
找到使用某个udp端口号的进程



# lsof -i udp:53
同样的,也可以找到使用某个tcp端口的进程:



# lsof -i tcp:80
也可以查找ipv4 ipv6链接的进程



# lsof -i 4



8.找到某个用户的所有网络连接



# lsof -a -u hacker -i
使用-a将-u和-i选项组合可以让lsof列出某个用户的所有网络行为。



9.列出所有NFS(网络文件系统)文件



# lsof -N
这个参数很好记,-N就对应NFS。



10.列出所有UNIX域Socket文件



# lsof -U
这个选项也很好记,-U就对应UNIX。



11.列出所有对应某个组id的进程



# lsof -g 1234
进程组用来来逻辑上对进程进行分组,这个例子查找所有PGID为1234的进程打开的文件。



列出所有与某个描述符关联的文件



lsof -d 2


这个命令会列出所有以描述符2打开的文件。



你也可以为描述符指定一个范围:



lsof -d 0-2


这会列出所有描述符为0,1,2的文件。



-d选项还支持其它很多特殊值,下面的命令列出所有内存映射文件:



lsof -d mem


txt则列出所有加载在内存中并正在执行的进程:



lsof -d txt


输出使用某些资源的进程pid



lsof -t -i


-t选项输出进程的PID,你可以将它和-i选项组合输出使用某个端口的进程的PID,下面的命令将会杀掉所有使用网络的进程:



kill -9 lsof -t -i


循环列出文件



lsof -r 1


-r选项让lsof可以循环列出文件直到被中断,参数1的意思是每秒钟重复打印一次,这个选项最好同某个范围比较小的查询组合使用,比如用来监测网络活动:



lsof -r 1 -u john -i -a


最后你可以通过man lsof来了解关于lsof的完整文档,或者通过lsof -h查看。



https://www.cnblogs.com/qzxbeichen/p/6595478.html


Category linux