TCP网络编程总结

1.TCP交互流程

在这里插入图片描述
1.服务器根据地址类型(ipv4, ipv6)、socket类型、协议创建socket。
2.服务器为socket绑定IP地址和端口号。
3.服务器socket 监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开。
4.客户端创建socket。
5.客户端打开socket,根据服务器IP地址和端口号试图连接服务器socket。
6.服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直到客户端返回连接信息后才返回,开始接收下一个客户端谅解请求。
7.客户端连接成功,向服务器发送连接状态信息。
8.服务器accept方法返回,连接成功。
9.客户端向socket 写入信息。
10.服务器读取信息。
11.客户端关闭。
12.服务器端关闭。

2.TCP网络编程API

1.socket函数
int socket(int domain ,int type , int protocol) ;
1.domain :即协议域,又称为协议族(family) 。常用的协议族有: AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX, Unix域socket )、AF_ROUTE等。
2.type :指定socket类型。常用的socket类型有: SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。其中, SOCK_STREAM表示提供面向连接的稳定数据传输,即TCP协议。SOCK_DGRAM 表示使用不连续、不可靠的数据包连接。
3.protocol :指定协议。常用的协议有, IPPROTO_TCP , IPPTOTO_UDP , IPPROTO_SCTP 、IPPROTO_TIPC 等,它们分别对应TCP 传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket 。这个socket描述字和文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。
当调用socket创建一个socket时,返回的socket描述字它存在于协议族(addressfamily, AF_XXX )空间中,但没有一个具体的地址。
套接字描述符是一个整数类型的值。每个进程的进程空间里都有一个套接字描述符表,该表中存放着套接字描述符和套接字数据结构的对应关系。
根据套接字描述符就可以找到其对应的套接字数据结构。套接字数据结构都存放在操作系统的内核缓冲里。
一个套接字由相关五元组构成:协议、本地地址、本地端口、远程地址、远程端口。

2.bind函数
int bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen) ;
1.sockfd :即socket描述字,它是通过socket()函数创建来唯一标识一个socket的。bind()函数就是将给这个描述字绑定一个名字。
2.addr : 一个const struct sockaddr*指针,指向要绑定给sockfd的协议地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同。
3.addrlen :对应的是地址的长度。
bind()函数把一个地址族中的特定地址赋给socket。
通常服务器端在调用listen之前会调用bind();而客户端就不用调用,而是在connect()时由系统随机生成一个。
返回值:如果函数执行成功,返回值为0 , 反之为SOCKET_ERROR。

3.listen函数
int listen(int sockfd , int backlog) ;
listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。
socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型,等待客户的连接请求。

4.connect函数
int connect(int sockfd , const struct sockaddr *addr, socklen_ t addrlen) ;
connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。
客户端通过调用connect 函数来建立与TCP服务器的连接。

5.accept函数
int accept(int sockfd, struct sockaddr *addr, socklen_t addrlen) ;
accept函数的第一个参数为服务器的socket描述字; 第二个参数为指向struct sockaddr
的指针,用于返回客户端的协议地址;第三个参数为协议地址的长度。
如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字,代表与返回客户的TCP连接。
accept的第一个参数为服务器的socket描述字,是服务器开始调用socket()函数生成的,称为监听socket描述字;而accept函数返回的是己连接的socket描述字。
一个服务器通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的巳连接socket描述字就被关闭。

6.read和write函数
read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()
最常用的是read()和write():
read()的函数原型是:
ssize_t read(int fd, void *buf, size_t count);
1.socket 描述字fd;
2.缓冲区buf;
3.缓冲区长度count 。
read()函数是负责从fd中读取内容。
当读取成功时,read()返回实际所读的字节数,如果返回的值是0表示已经读到文件的结束了,小于0表示出现了错误。如果错误为EINTR
说明读是由中断引起的,如果是ECONNREST 表示网络连接出了问题。
write()的函数原型是:
ssize_t write(int fd, const void *buf, size_t count);
1.socket 描述字fd;
2.缓冲区buf;
3.缓冲区长度count 。
网络程序中,当向套接字文件描述符写时有两种可能:
1.write的返回值大于0,表示写了部分或者是全部的数据;
2.返回的值小于0,此时出现了错误。实际中要根据错误类型来处理。如果错误为EINTR表示在写的时候出现了中断错误。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接)。

7.close函数
需要包含的头文件是:
#include <unistd.h>
close 的函数原型是:
int close(int fd) ;
close一个TCP socket的默认行为时,会把该socket标记为以关闭,然后立即返回到调用进程。该描述字不能再由调用进程使用,也就是说不能再作为read或write的第一个参数。

3.TCP协议选项

TCP头部的选项部分是为了TCP适应复杂的网络环境和更好地服务于应用层而进行设计的。
1.SO_REUSEADDR
例如:
setsockopt(fd, SOL_SOCKET, SO_ REUSEADDR , (const void *) &nOptval,sizeof (int))

  1. SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知的端口,并且以前建立的将此端口用做它们的本地端口的连接仍存在。
  2. SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。
  3. SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个进程捆绑的指定不同的本地IP地址即可。
  4. SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。

2.SO_ REUSEPORT
1)此选项允许完全重复捆绑,但只有在想捆绑相同IP地址和端口的套接口都指定了此套接口选项才行。
2)如果被捆绑的地址是一个多播地址,则SO_REUSEADDR 和SO_REUSEPORT等效。

3.TCP_NODELAY/TCP_CHORK
Nagle算法:如果发送端欲多次发送包含少量字符的数据包,则发送端会先将第一个小包发送出去,而将后面到达的少量字符数据都缓存起来而不立即发送,直到收到接收端对前一个数据包报文段的ACK确认为止,或当前字符属于紧急数据,或者积攒到了一定数量的数据(比如缓存的字符数据已经达到数据包报文段的最大长度)等多种情况才将其组成一个较大的数据包发送出去。
TCP中的Nagle算法默认是启用的。
TCP_NODELAY 和TCP_CORK基本上控制了包的“Nagle化”,TCP_NODELAY 和TCP_CORK 都禁掉了Nagle算法。
TCP_NODELAY不使用Nagle 算法,不会将小包进行拼接成大包再进行发送,而是直接将小包发送出去。
当在传送大量数据的时候,为了提高TCP发送效率,可以设置TCP_CORK, CORK就是“塞子”的意思,它会尽量在每次发送最大的数据量。当设置了TCP_CORK后, 会有200ms阻塞,当阻塞时间过后,数据就会自动传送。

4.SO_LINGER
linger是延迟延缓的意思,这里的延缓是指面向连接的socket的close操作。
控制SO_LINGER 通过下面一个结构:
struct linger{
int l_onoff ; / 0=off , nonzero=on * /
int l_linger ; / * linger time , POSIX specifies units as seconds
/
}

  1. l_onoff设置为0 ,选项被关闭。
  2. l_onoff 设置为非0, l_linger 被设置为0,这种关闭方式称为“强制” 或“失效”关闭。
  3. l_onoff 设置为非0, l_linger 被设置为非0 ,则close()调用阻塞进程,这种关闭称为“优雅地”关闭,

5.TCP_DEFER_ACCEPT
defer accept,从字面上理解是推迟接收,实际上是当接收到第一个数据之后,才会创建连接。
例如:
val = 5 ;
setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ;
里面val的单位是秒(s),注意如果打开这个功能, kernel在val 时间之内还没有收到数据,不会继续唤醒进程,而是直接丢弃连接。

6.SO_KEEPALIVE
SO_KEEPALIVE用于保持连接检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。
设置该选项后,如果2h内在此套接口的任一方向都没有数据交换,TCP就自动给对方发一个保持存活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节。
SO_KEEPALIVE 的3个参数:

  1. tcp_keepalive_intvl,保活探测消息的发送频率。默认值为75s。
  2. tcp_ keepalive_probes, TCP发送保活探测消息以确定连接是否已断开的次数,其默认值为9(次)。
  3. tcp_keepalive_time ,在TCP保活打开的情况下, 最后一次数据交换到TCP发送第一个保活探测消息的时间,即允许的持续空闲时间,其默认值为7200s (2h)。
    设置SO_KEEPALIVE选项来开启KEEPALIVE, 然后通过TCP_KEEPIDLE 、TCP_KEEPINTVL
    和TCP_KEEPCNT设置keepalive的开始时间、间隔、次数等参数,使用方法如下:
    int keepalive = 1 ;
    setsockopt(Incomingsock, SOL_ SOCKET , SO_ KEEPALIVE , (void * ) (&keepalive), (socklen_t)sizeof(keepalive)) ;
    int keepalive_ time = 30;
    setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE , (void*) (&keepalive_time) , (socklen_ t)sizeof(keepalive_time)) ;
    int keepalive_ intvl = 3;
    setsockopt (incomingsock , IPPROTO_TCP, TCP_KEEPINTVL , (void*) (&keepalive_intvl) , (socklen_ t)sizeof(keepalive_intvl)) ;
    int keepalive_probes= 3;
    setsockopt (incomingsock , IPPROTO_TCP , TCP_KEEPCNT, (void*) ( &keepalive_probes) , (socklen_ t)sizeof(keepalive_probes)) ;

7.SO_SNDTIMEO和SO_RCVTIMEO
SO_SNDTIMEO 和SO_RCVTIMEO两项分别设置socket的发送和接收超时时间,它们都接收一个timeval结构作为参数,当timeval结构为0时,表示选项无效。

8.SO_RCVBUF和SO_SNDBUF
每个TCP套接字都有一个发送缓冲区和一个接收缓冲区,每个UDP套接字都有一个接收缓冲区。使用SO_RCVBUF和SO_SNDBUF这两个套接口选项可以改变默认缓冲区大小。

4.网络字节序与主机序

不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,称为主机序
1.Little Endian:将低序字节存储在起始地址;
2.Big Endian ,将高序字节存储在起始地址。
所有网络协议也都是采用Big Endian的方式来传输数据的。所以有时也会把Big Endian方式称之为网络字节序

5.网络IO模型

4种网络IO模型
1.阻塞IO模型
在Linux,默认情况下所有的socket 都是阻塞的。
阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,不需要等到IO操作彻底完成。
在这里插入图片描述
2.非阻塞IO模型
在Linux下,可以通过设置socket使IO变为非阻塞状态。
在非阻塞式IO中,用户进程其实需要不断地主动询问kernel数据是否准备好。非阻塞的接口相比于阻塞型接口的显著差异在于被调用之后立即返回。
使用如下的函数可以将某句柄归设为非阻塞状态:
fcntl( fd,F_SETFL,O_NONBLOCK );
在非阻塞状态下, recv()接口在被调用后立即返回,返回值代表了不同的含义,如下所述:
1)recv()返回值大于0,表示接收数据完毕,返回值即是接收到的字节数。
2)recv()返回0,表示连接已经正常断开。
3)recv()返回-1,且errno 等于EAGAIN ,表示recv操作还没执行完成。
4)recv()返回-1,且errno 不等于EAGAIN ,表示recv操作遇到系统错误errno。
上述模型绝不被推荐,因为循环调用recv()将大幅度占用CPU使用率。
在这里插入图片描述
3.多路IO复用模型
多路IO复用,有时也称为事件驱动IO。它的基本原理就是有个函数(如select)会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
当用户进程调用了select ,那么整个进程会被阻塞,而同时,内核会“监视”所有select负责的socket ,当任何一个socket中的数据准备好了, select就会返回。这个时候用户进程再调用read操作,将数据从内核拷贝到用户进程。
select /epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
在多路复用IO模型中,对于每一个socket,一般都设置成为非阻塞的,但是,整个用户的进程其实是一直被阻塞的。只不过进程是被select 这个函数阻塞,而不是被socket IO 阻塞。因此使用select()的效果与非阻塞IO类似。
在这里插入图片描述
4.异步IO模型
用户进程发起read操作之后,立刻就可以开始去做其他的事;而另一方面,从内核的角度,当它收到一个异步的read请求操作之后,首先会立刻返回,所以不会对用户进程产生任何阻塞。然后,内核会等待数据准备完成,然后将数据拷贝到用户内存中,当这一切都完成之后,内核会给用户进程发送一个信号,返回read操作已完成的信息。
在这里插入图片描述
各个IO模型的比较:
在这里插入图片描述
多路IO复用模型检查使用函数:
1.select函数
select 的函数原型:
int select (int maxfdp,fd_set *readfds, fd_set *writefds, fd_set errorfds, struct timevaltimeout) ;

  1. maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1。
  2. readfds是指向fd_set 结构的指针,这个集合中应该包括文件描述符。因为要监视文件描述符的读变化的,即关心是否可以从这些文件中读取数据。
  3. writefds是指向fd_set 结构的指针,这个集合中应该包括文件描述符。因为要监视文件描述符的写变化的,即关心是否可以向这些文件中写入数据。
  4. errorfds同上面两个参数的意图,用来监视文件错误异常。
  5. timeout是select的超时时间, 这个参数至关重要,它可以使select 处于3种状态:
    1.若将NULL 以形参传入,即不传入时间结构,就是将select 置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
    2.若将时间值设为0 ,就变成一个纯粹的非阻塞函数,不管文件描述符是否再有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
    3.timeout 的值大于0 ,这就是等待的超时时间,即select在timeout 时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
    6)返回值:准备就绪的描述符数,若超时则返回0 ,若出错则返回-1。

结构体fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄,这可以认为是常说的普通意义的文件;fd_set 集合可以通过一些宏由人为来操作,比如以下代码:
fd_set set ;
FD_ZERO(&set) ; /*将set 清零*/
FD_SET(fd , &set) ; /*将fd 加入set */
FD_CLR(fd, &set) ; /*将fd 从set 中清除*/
FD_ISSET(fd, &set) ; /*如果fd在set 中则真*/
结构体timeval 是一个常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。

2.poll函数
poll所需要的头文件和函数原型如下所示:
#include<poll.h>
int poll(struct pollfd * fds,unsigned int nfds,int timeout);
pollfd结构体定义如下所示:
struct pollfd {
int fd; /*文件描述符*/
short events;/*等待的事件*/
short revents;/*实际发生了的事件*/
};
每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。
每个结构体的events 域是监视该文件描述符的事件掩码,由用户来设置这个域的属性。
revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域;
events域中请求的任何事件都可能在revents域中返回。
poll事件:
在这里插入图片描述
实际上这些事件在events域中无意义因为它们总会在合适的时候从revents中返回。
timeout 参数指定等待的毫秒数,无论IO 是否准备好, poll 都会返回。
timeout 指定为负数值时表示无限超时,使poll() 一直挂起直到一个指定事件发生;timeout为0指示poll调用立即返回并列出准备好IO的文件描述符,但并不等待其他的事件。这种情况下,poll()的返回值, 一旦被选举出来,立即返回。
成功时,poll()返回结构体中revents域不为0的文件描述符个数:如果在超时前没有任何事件发生,poll()返回0 。失败时,poll()返回-1,并设置errno 为下列值之一:

  1. EBADF: 一个或多个结构体中指定的文件描述符无效。
  2. EFAULTfds:指针指向的地址超出进程的地址空间。
  3. EINTR: 请求的事件之前产生一个信号,调用可以重新发起。
  4. EINVALnfds:参数超出PLIMIT_NOFILE值。
  5. ENOMEM:可用内存不足,无法完成请求。

3.epoll函数
epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间之间的数据拷贝只需一次。
epoll 接口:
使用epoll 必须包含下面的这个头文件:
#include <sys/epoll.h>
epoll操作过程需要3个接口:
int epoll_create(int size) ;
创建一个epoll的句柄,size用来告诉内核要监听的数目。当创建好epoll句柄后,它就会占用一个fd值,在Linux下如果查看/proc/ 进程的id/fd/,是能够看到这个fd值的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。
*int epoll_ctl(int epfd , int op , int fd , struct epoll_event event);
epoll的事件注册函数,它不同于select()在监听事件时告诉内核要监听什么类型的事件,而是先注册要监听的事件类型。
第1个参数是epoll_create()的返回值
第2个参数表示动作,用3 个宏来表示:
1.EPOLL_CTL_ADD ,注册新的fd到epfd 中;
2.EPOLL_CTL_MOD ,修改已经注册的fd的监听事件;
3.EPOLL_ CTL _DEL :从epfd 中删除一个fd。
第3个参数是需要监听的fd
第4 个参数是告诉内核需要监听什么事
struct epoll _event结构如下:

struct epoll_event (
_uint32_t events; /* Epoll events /
epoll_data_t data ; /
User data variable * /
} ;
events 可以是以下几个宏的集合:
1.EPOLLIN,表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
2.EPOLLOUT,表示对应的文件描述符可以写;
3.EPOLLPRI,表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
4.EPOLLERR,表示对应的文件描述符发生错误;
5.EPOLLHUP, 表示对应的文件描述符被挂断;
6.EPOLLET ,将EPOLL 设为边缘触发( Edge Triggered )模式, 这是相对于水平触发( LevelTriggered )来说的;
7.EPOLLONESHOT ,只监听一次事件, 当监听完这次事件之后,如果还需要继续监听这个socket 的话,需要再次把这个socket加入到EPOLL队列里。

int epoll_wait (int epfd, struct epoll_ event * events , int maxevents , int timeout);
等待事件的产生,类似于select()调用。
参数events用来从内核得到事件的集合。
maxevents告诉内核这个events有多大,且maxevents 的值不能大于创建epoll_create()时的size。
参数timeout是超时时间(ms为单位,0会立即返回,-1将不确定或称永久阻塞)。
该函数返回需要处理的事件数目如返回0表示已超时。

6.网络分析工具

1.ping介绍
ping 发送一个ICMP (Internet Control Messages Protocol ,因特网信报控制协议),请求消息给目的地并报告是否收到所希望的ICMP echo ( ICMP 回声应答),它是用来检查网络是否通畅或者网络连接速度的命令。
Linux的ping语法和Windows的差不多,但是Linux 的ping 数据包是64Byte ,而Windows 的是32Byte,Windows下默认发送4次数据包后结束, Linux 下的ping程序默认不停发送数据包,直到用户手动停止(停止指令是Ctrl+c)。
ping指的是端对端连通,通常用来作为可用性的检查。
ping的使用:
应用格式:ping空格IP地址,该命令还可以加许多参数使用。
使用ping检查连通性有以下6个步骤:
1)使用ipconfig/all 观察本地网络设置是否正确。
2) ping 127.0.0.l ,来检查本地的TCP/IP 协议有没有设置好。
3) ping 本机IP地址,这样是为了检查本机的IP地址是否设置有误。
4) ping 本网网关或本网IP地址,这样的是为了检查硬件设备是否有问题,也可以检查本机与本地网络连接是否正常。
5) ping 本地DNS地址,这样做是为了检查本地DNS服务器是否工作正常。
6) ping 远程IP地址,这主要是检查本网或本机与外部的连接是否正常。

2.tcpdump介绍
tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对协议、主机、网络或端口的过滤,并提供and、or,,not 等逻辑语句来帮助去掉无用的信息。
tcpdump的使用:
tcpdump 采用命令行方式:
tcpdump [ -adeflnNOpqStvx l [ -c 数量] [ -F 文件名]
[ -i 网络接口] [ -r 文件名] [ -s snaplen ]
[ -T 类型] [ -w 文件名] [表达式]
在表达式中一般包含如下几种类型的关键字:
1)关于类型的关键字,主要包括host 、net 、port 等。如果没有指定类型,默认的类型是host。
2)确定传输方向的关键字,主要包括src 、dst 、dst or src 、dst 、src等,这些关键字指明了传输的方向。如果没有指明方向关键字,则默认是src or dst 关键字。
3)协议的关键字,主要包括fddi、ip、arp、rarp、tcp、udp等类型。如果没有指定任何协议,则tcpdump将会监听所有协议的信息包。
4)其他重要的关键字如下:gateway、broadcast、less、greater等,还有3种逻辑运算:取非运算not/!,与运算and/&&;或运算or/I I;这些关键字可以组合起来构成强大的组合条件来满足人们的需要。

3.netstat介绍
netstat命令用于显示与IP、TCP、UDP 和ICMP 协议相关的统计数据, 一般用于检验本机各端口的网络连接情况。netstat 是在内核中访问网络及相关信息的程序,它能提供TCP 连接、对TCP 和UDP的监听及获取进程内存管理的相关报告。
netstat的使用:
netstat [-acCeFghilMnNoprstuvVwx] [-A<网络类型>] [–ip]
常见参数:
-a (all)显示所有选项,默认不显示LISTEN相关
-t (tcp)仅显示tcp 相关选项
-u (udp)仅显示udp 相关选项
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在Listen(监听)的服务状态
-p 显示建立相关链接的程序名
-r 显示路由信息,路由表
-e 显示扩展信息,例如uid等
-s 按各个协议进行统计
-c 每隔一个固定时间,执行该netstat命令。
提示:LISTEN 和LISTEN工NG 的状态只有用-a 或者-l才能看到。

4.Isof介绍
lsof (list open file)是一个列出当前系统打开文件的工具。在Linux 环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。
在终端下输入lsof 即可显示系统打开的文件,因为lsof 需要访问核心内存和各种文件,所以必须以root用户的身份运行才能够充分地发挥其功能。
lsof的使用:
lsof [options] filename
常用参数:
lsof filename 显示打开指定文件的所有进程
lsof - a 表示两个参数都必须满足时才显示结果
lsof -c string 显示COMMAND列中包含指定字符的进程所有打开的文件
lsof -u username 显示所属user进程打开的文件
lsof -g gid 显示归属gid 的进程情况
lsof +d /DIR/ 显示目录下被进程打开的文件
lsof +D /DIR/ 同上,但是会搜索目录下的所有目录,时间相对较长
lsof -d FD 显示指定文件描述符的进程
lsof -n 不将IP转换为hostname,缺省是不加上-n 参数
lsof -i 用以显示符合条件的进程情况

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值