0
点赞
收藏
分享

微信扫一扫

【iOS】ViewController的生命周期

云岭逸人 2023-09-18 阅读 46

000

TCP协议

1.连接管理机制

正常情况下,TCP需要经过三次握手建立连接+四次挥手断开链接,下面看一个图:
0001

  • 服务器的状态变化:
  • 客户端状态变化

2.再谈WAIT_TIME状态

2.1理解WAIT_TIME状态

现在做一个测试,首先启动server,然后启动client,然后用Ctrl-C使server终止,这时马上再运行server, 结果是:
0007
这是因为,虽然server的应用程序终止了,但TCP协议层的连接并没有完全断开,因此不能再次监 听同样的server端口.
我们用netstat命令查看一下:
0008

  • 为什么TIME_WAIT的时间是2MSL?

2.2解决TIME_WAIT状态引起的bind失败的方法

  • 在server的TCP连接没有完全断开之前不允许重新监听, 某些情况下可能是不合理的
  • setsockopt函数介绍
  • 实际案例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

int main() {
    // 创建 TCP 套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 设置 TCP 连接超时时间为 5 秒
    struct timeval timeout;
    timeout.tv_sec = 5; // 5 秒
    timeout.tv_usec = 0;

    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
        perror("setsockopt");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 尝试连接到远程服务器
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(80); // HTTP 默认端口
    inet_pton(AF_INET, "www.example.com", &(server_addr.sin_addr));

    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    printf("Connected to www.example.com\n");

    // 在这里可以进行后续的数据交换或操作

    // 关闭套接字
    close(sockfd);

    return 0;
}

在上面的示例中,我们创建了一个 TCP 套接字,并使用 setsockopt 设置了接收超时时间为 5 秒。然后,我们尝试连接到 www.example.com 的 HTTP 服务。如果连接在 5 秒内成功建立,将打印 “Connected to www.example.com”。否则,连接超时会导致 connect 失败,错误处理部分将处理超时情况。

2.3监听套接字listen第二个参数介绍

if(listen(listenSock,2)<0)
{
exit(3);
}

在这里的2表示什么?当服务器在处理其他请求时来不及处理新的链接请求,监听套接字所维护的最大链接数为:2+1,相当于排队
listen底层有个backlog来维护:

  • 下面是关于 backlog 的一些重要信息:

这其实也是一种池化技术,进行排队等待处理,

  • 排队的意义在于:可以让服务器在有闲置的情况下,拿到链接处理相关任务,减少资源的闲置,提高利用率。
  • 为什么不能设置过长:1.太长的排队影响处理效率,新的任务需要等待很长的时间才能处理,影响客户体验;2.队列也是会占用系统资源的,设置过长占用过多的系统资源,反而可能导致服务器的效率降低!

3.滑动窗口

3.1介绍

  • 没有滑动窗口情况下通信:
    0009
    既然这样一发一收的方式性能较低, 那么我们一次发送多条数据, 就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了).

0010

3.2丢包情况分析

  • 情况一: 数据包已经抵达, ACK被丢了
    0012
    这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认,也就是说:主机A给主机B发送1~6000号数据包,主机B已经收到了,但是其中的确认请求1001(确认前1000号)和2001、3001、4001、主机A都没有收到,但是6001收到了,这就说明前6000号数据包已经成功接收!!! 如果说出现这样一种情况:1000–2000号数据包丢了,其他的数据包成功接收,那么主机B并不会确认6001号,而是确认1001,表示后面的丢失,这时候就要进行重传!

  • 情况二: 数据包就直接丢了.
    0013

  • 这种机制被称为 “高速重发控制”(也叫 “快重传”).

4.流量控制

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送,就会造成丢包, 继而引起丢包重传等等一系列连锁反应.
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);

0014

5.拥塞控制

5.1介绍

  • 拥塞控制在现代计算机网络中至关重要,它确保了网络的稳定性和性能。通过动态调整数据包的发送速率和响应网络拥塞,拥塞控制确保了数据的可靠传输,并提供了更好的用户体验。不同的拥塞控制算法和机制可以根据网络类型和需求进行选择和配置。

5.2慢启动

0014

  • 像上面这样的拥塞窗口增长速度, 是指数级别的. “慢启动” 只是指初使时慢, 但是增长速度非常快.

0015
当TCP开始启动的时候, 慢启动阈值等于窗口最大值;
在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1;
少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

6.捎带应答、延时应答

相关博客: 点击跳转

举报

相关推荐

0 条评论