TCP长连接详解

一、什么是TCP长连接

TCP连接在网络通信中绝对是一个基础、关键而又常见的概念。而长连接又是TCP连接的一种特殊形态。所谓TCP长连接,指的是建立起来的TCP连接不会轻易的中断或关闭,而是一直保持连接状态,直至完成或出现意外断连。

与之对应的是短连接,即数据传输一次完成后,连接就会自动关闭。相比之下,长连接有很多优点,因此在实际开发中非常常用。我们可以通过几种方式来实现TCP长连接:保持TCP连接处于连接状态、服务器空闲状态发送心跳包来实现保活机制、应用层心跳等,后面我们会详细介绍这些内容。

二、TCP长连接的优点和缺点

长连接的优点主要有以下几点:

1、减少了TCP的握手次数,减少了资源的占用。

2、避免了服务端资源的频繁分配,提高了性能。

3、客户端可以更快速的获取到服务器上的数据,同时也提高了用户的体验。

然而,长连接也存在缺点:

1、可能存在部分数据丢失。长连接在通信过程中,因为网络的原因,一些数据可能会丢失,但不会造成太大的影响。

2、连接长久不关闭会对服务器端的性能造成威胁。因为长连接需要服务器端占用一定的资源保持状态,如果长时间不关闭就会对服务器造成一定的负担。

三、保持TCP连接处于连接状态

我们可以通过设置TCP的keep-alive属性让TCP连接一直处于连接状态。keep-alive会定时地给服务器发一个TCP包以判断连接是否终止,从而保持连接不断开。

// C语言实现,设置TCP_KEEPALIVE属性
int keepalive = 1;      //开启KEEPALIVE属性
int keepidle = 60;      //如果60秒内没有任何数据交互,TCP会发送检验包(称为保持存活探测分节)。
int keepinterval = 5;   //检验包的发送间隔默认为75秒收不到保持存活探测分节后,才会发送第一个探测分节
int keepcount = 3;      //如果第1次检测包发送失败,则每隔5秒发送第二个检测包,最多发送3个检测包。如果3次都没成功,就当连接失效断掉。

setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));  //开启keepalive功能
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&keepidle, sizeof(keepidle));     //设置当有数据报要发送时Kernel会等待多长时间,才会发这个数据报。单位为秒。
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepinterval, sizeof(keepinterval));  //设置每次发送数据报的时间间隔,默认为75秒。
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepcount, sizeof(keepcount));   //设置发送保持存活探测分节的次数。默认是9次。

四、服务器空闲状态发送心跳包实现保活机制

除了设置TCP的keep-alive属性之外,还可以采用心跳机制来保持TCP长连接。服务器不断地向客户端发送心跳包来判断连接的状态,从而实现保活机制。实现起来比设置TCP的keep-alive属性要容易一些。

//C语言实现
int SendData(int fd, char *buffer, int len, int flags)
{
    int nsend = 0;
    nsend = send(fd, buffer, len, flags);
    if (nsend == -1) 
    { 
        //send 发送失败
        if(errno == EINTR) /*信号中断*/
        {
            //稍后重发
        } 
        else if(errno == EAGAIN || errno == EWOULDBLOCK) /*一般错误类型*/
        {
            //稍后重发
        }
        else /*其他错误类型,关闭fd*/
        {
            //CLOSED端口fd
        }
    }
    return nsend;
}

int recv_with_timeout(int fd, char *buf, int data_size, int timeout)
{
    fd_set fds;
    struct timeval tv;
    int ret = 0;

    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    tv.tv_sec = timeout;
    tv.tv_usec = 0;

    ret = select(fd+1, &fds, NULL, NULL, &tv);
    switch(ret)
    {
        case -1: /* error occurred */
            perror("select error:");
            return -1;

        case 0: /* timed out */

            return -2;

        default: /* data ready */
            if (FD_ISSET(fd, &fds))
                return recv(fd, buf, data_size, 0);
    }

    return -3;
}

char buffer[1024];
while(true)
{
    SendData(fd, "HeartBeat", sizeof("HeartBeat"), 0); //服务器定时发送心跳包
    int res = recv_with_timeout(fd, buffer, 4, 5); //设置5秒的等待时间
    if(res == -2) 
    {
        //客户端长时间未响应,服务端可以关闭连接
    }
}

五、应用层心跳

应用层心跳,就是通过应用程序在长连接上发送一定类型的消息,以达到保持连接状态的目的。在实际中,应用层心跳的灵活性和可控性都较高,但也需要我们自己来设计和实现心跳包的规则。

//C语言实现
while(true)
{
    SendData(fd, "HeartBeat", sizeof("HeartBeat"), 0); //发送应用层心跳包
    sleep(5);  //定时发送心跳
}

六、结束语

以上就是关于TCP长连接的详细讲解,包括了长连接的定义、优缺点、保持TCP连接处于连接状态、服务器空闲状态发送心跳包实现保活机制、以及应用层心跳等多个方面。我们可以结合实际项目和需求来选择不同的实现方式,以达到最佳的效果。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/198658.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-04 10:26
下一篇 2024-12-04 10:26

相关推荐

  • NodeJS 建立TCP连接出现粘包问题

    在TCP/IP协议中,由于TCP是面向字节流的协议,发送方把需要传输的数据流按照MSS(Maximum Segment Size,最大报文段长度)来分割成若干个TCP分节,在接收端…

    编程 2025-04-29
  • TCP发送的数据包发布全

    TCP协议是一种可靠的面向连接的协议,而数据包的发送则是其重要组成部分,本文将从多个方面对TCP发送的数据包发布全进行详细阐述。 一、数据包的概念 数据包指的是网络传输过程中,为了…

    编程 2025-04-27
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25

发表回复

登录后才能评论