TIME_WAIT状态套接字重新使用

news/2024/5/17 19:18:56 标签: tcp

《TIME_WAIT相关知识》里边有相关理论知识。
《TIME_WAIT状态TCP连接导致套接字无法重用实验》有相关实验。

现代Linux的TCP协议栈已经做了许多升级,所以可以让我们直接重用TIME_WAIT状态套接字而不会引起问题。下边是优化的内容:

1.新连接的SYN告知序列号比原来TIME_WAIT老连接末序列号要大,所以就可以通过序列号分辨出来新老连接。
2.开启tcp_timestamps,这样就让新连接时间戳比旧连接时间戳大,这样可以通过检查时间戳来判断新老连接。

在这样两重优化下,重用TIME_WAIT状态连接就不会产生任何问题了。

int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

SO_REUSEADDR用来告诉操作系统内核,如果端口已被占用,但是 TCP 连接状态位于 TIME_WAIT ,可以重用端口。这段代码需要放到socket函数和bind函数之间。
下边是timeWaitSetsockopt.c完整代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h>
#include<signal.h>

void error_handling(char *buf);

#define  MAXLINE     1024
static int count;
static void sig_int(int signo) {
    printf("\nreceived %d datagrams\n", count);
    exit(0);
}
int main(int argc, char **argv) {
    if (argc != 2) {
        error_handling("usage: select01 <IPaddress> or <Port>");
    }



    int serv_sock = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(atoi(argv[1]));
    // SO_REUSEADDR用来告诉操作系统内核,如果端口已被占用,但是 TCP 连接状态位于 TIME_WAIT ,可以重用端口
    int on = 1;
    setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    if(bind(serv_sock, (struct sockaddr*) &server_addr, sizeof(server_addr))==-1){
        fprintf(stderr, "error in bind: %s (%d)\n", strerror(errno), errno);
                    exit(errno);
    }
        if(listen(serv_sock, 5)==-1){
        fprintf(stderr, "error in listen: %s (%d)\n", strerror(errno), errno);
                    exit(errno);
    }


    signal(SIGPIPE, sig_int);


     int connfd;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);

    if ((connfd = accept(serv_sock, (struct sockaddr *) &client_addr, &client_len)) < 0) {
        printf("accept failed");
        exit(0);
    }

    char message[MAXLINE];
    count = 0;
    int n;
    for (;;) {
        int n = read(connfd, message, MAXLINE);
        if (n < 0) {
            fprintf(stderr, "error in read: %s (%d)\n", strerror(errno), errno);
                    exit(0);
        } else if (n == 0) {
            fprintf(stderr, "client closed: %s (%d)\n", strerror(0), 0);
            exit(0);
        }
        message[n] = 0;
        printf("received %d bytes: %s\n", n, message);
        count++;
    }
}
void error_handling(char *buf)
{
        fputs(buf, stderr);
        fputc('\n', stderr);
        exit(1);
}

在服务器端sudo gcc timeWaitSetsockopt.c -o timeWaitSetsockopt进行编译,sudo ./timeWaitSetsockopt 8080启动程序。
在这里插入图片描述

在客户端使用sudo telnet 127.0.0.1 8080进行连接,然后输入good之后按下回车键。
在这里插入图片描述

然后在服务器端同时按住ctrl+c关闭程序,之后快速再使用sudo ./timeWaitSetsockopt 8080启动程序,然后快速在客户端使用sudo telnet 127.0.0.1 8080进行连接,输入network之后按下回车键,还是需要在服务器端快速按下sudo netstat -altnp | grep 8080看一下连接状态,这些动作只要够快就可以出现两条记录。
在这里插入图片描述


http://www.niftyadmin.cn/n/5220160.html

相关文章

【JavaScript框架】2024年需要学习的顶级JavaScript框架:Blitz、SolidJS、Svelte等

如今&#xff0c;Web开发人员面临两大问题。 第一个是如何自动化繁琐的web开发工作。要为标准web应用程序设置一个项目&#xff0c;您必须花费宝贵的时间学习用于常见任务的几个库&#xff0c;如身份验证和数据库处理&#xff0c;并将它们捆绑在一起。第二个问题是如何使网络应…

Linux基础项目开发1:量产工具——程序框架(一)

前言&#xff1a; 前面已经将Linux应用开发基础知识学习完了&#xff0c;现在让我们来做个小项目练练手&#xff0c;对之前的一些知识点进行一个更加具体详细的认识与了解&#xff0c;我们要进行的项目名称为&#xff1a;电子产品量产测试与烧写工具&#xff0c;这是一套软件&a…

【C++】探索C++模板编程

文章目录 什么是C模板&#xff1f;模板的基本语法类型模板参数模板函数的示例类模板的示例总结 C模板是一种强大的编程工具&#xff0c;它可以实现泛型编程&#xff0c;使代码更加灵活和可重用。本篇博客将介绍C模板的基本语法、类型模板参数和模板函数的使用&#xff0c;并通过…

振南技术干货集:znFAT 硬刚日本的 FATFS 历险记(6)

注解目录 1、znFAT 的起源 1.1 源于论坛 &#xff08;那是一个论坛文化兴盛的年代。网友 DIY SDMP3 播放器激起了我的兴趣。&#xff09; 1.2 硬盘 MP3 推了我一把 &#xff08;“坤哥”的硬盘 MP3 播放器&#xff0c;让我深陷 FAT 文件系统不能自拔。&#xff09; 1.3 我…

你了解Redis 的二进制安全吗

最近面试的时候被问到Redis 的二进制安全相关八股文面试题。Redis二进制安全内容比较多&#xff0c;以下是简单的总结大致的过程&#xff0c;需要深入学习的建议跳过 Redis是基于C语言进行开发的&#xff0c;而C语言中的字符串是二进制不安全的&#xff0c;所以Redis就没有直接…

零基础编程入门视频教程,零基础编程从哪学起,分享中文编程工具构件实例

零基础编程入门视频教程&#xff0c;零基础编程从哪学起&#xff0c;分享中文编程工具构件实例 1、零基础编程入门视频教程&#xff0c;系统化编程教程链接 https://jywxz.blog.csdn.net/article/details/134073098?spm1001.2014.3001.5502 2、零基础编程从哪学起 建议初学…

线程池的饱和策略有哪些?

线程池的饱和策略是指当线程池中的任务队列已满时&#xff0c;线程池如何处理新提交的任务。常见的饱和策略有以下几种&#xff1a; 阻塞策略 阻塞策略是指当线程池中的任务队列已满时&#xff0c;新提交的任务会等待队列中有空闲位置后再执行。这种策略可以避免过多的任务被…

操作系统 选择题 期末试题 考研真题 + 参考答案

1.&#xff08;考研真题&#xff0c;单项选择题&#xff09;单道批处理系统的主要缺点是&#xff08; &#xff09;。 A. CPU利用率不高 B.失去了交互性 C.不具备并行性 D.以上都不是 【参考答案】A 【解析】单道批处理系统的内存中只有一道程序&#xff0c;当该程序…