1.19号网络

超时检测

概念

1> 在网络通信中,有很多函数是阻塞函数,会导致进程的阻塞,例如:accept、recv、recvfrom、等等

2> 为了避免进程在阻塞函数处,无休止的等待,我们可以设置一个超时时间,当时间超时后,会从阻塞函数处立即返回,继续运行后续程序

自带超时检测的函数

select

//准备一个容器 fd_set readfds;

//清空容器 FD_ZERO(&readfds);

//将0号文件描述符放入集合中

FD_SET(0, &readfds);

struct timeval tv = {5, 0};

int res = select(1, &readfds, NULL, NULL, &tv);

poll

//定义一个等待容器数组

struct pollfd pfd;

//给结构体填充内容

pfd.fd = 0; pfd.events = POLLIN;

int res = poll(&pfd, 1, 5000);

不带超时参数的函数

setsockopt

//对套接字设置接收超时时间
    struct timeval tv;
    tv.tv_sec = 5;         //5秒
    tv.tv_usec = 0;      

    //设置超时
    if(setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))==-1)
    {
        perror("setsockopt error");
        return -1;
    }
 

alarm

也可以作为超时时间检测,在某个阻塞函数执行之前,可以启动一个定时器,当定时器时间到位后,会产生一个SIGALRM信号,默认操作是关闭进程,也可以将该信号捕获后处理其他操作

包头分析

以太网头

以太网中封装了源mac地址以及目的mac地址,还有ip类型,以太网又称之为mac头

IP头

两个IP地址:源IP与目的IP地址。

TTL:time to live, 指定数据帧可以最多经过几个路由器。当数据帧被目标方接收后,TTL清除为0.

UDP头

TCP头

Seq:序列号,占4个字节,用于给数据段进行编号的。所有非应答包的数据段,都有seq。

Ack:应答号,用于应答非应答包(握手包,挥手包,数据包)。告诉对方下一次从这个seq编号发送数据包。

SYN:握手包,连接的时候产生的包

FIN:挥手包,断开连接产生的包

PSH:数据包,传输数据时候产生的包

ACK:应答包

三次握手(重点)

1.19号网络_第1张图片

三次握手的发起方,肯定是客户端

  1. 第一次握手:客户端发送SYN包(SYN=1, seq=0)给服务器,并进入SYN_SENT状态,等待服务器返回确认包。
  2. 第二次握手:服务器接收到SYN包,确认客户端的SYN,发送ACK包(ACK=1 , ack=1),同时发送一个SYN包(SYN=1, seq=0),并进入SYN_RCVD状态。
  3. 第三次握手:客户端接收到服务器的SYN包,以及ACK包,进入establish状态,同时向服务器发送ACK包(ACK=1, ack=1)。此时三次握手包发送完毕,服务器也进入establish状态

四次挥手(重点)

四次挥手的发起方可能是服务器,也可能是客户端

  1. 第一次挥手,主动关闭方发送一个FIN包(FIN=1, seq = u)给被动方,进入FIN_WAIT_1状态;
  2. 第二次挥手:被动方接收到FIN包,给主动方发送一个ACK包(ACK=1, ack=u+1);并进入CLOKSE_WAIT状态。主动方接受到ACK包后,进入FIN_WAIT_2状态。如果有数据没有发送完毕,则继续发送,直到发送完毕为止;
  3. 第三次挥手:被动方发送一个FIN包(FIN=1, seq=w),进入LAST_ACK状态.
  4. 第四次挥手:主动关闭方收到FIN包,回复一个ACK包(ACK=1, ack=w+1)。被动关闭方收到主动关闭方的ACK后关闭连接。

你可能感兴趣的:(笔记)