优雅关闭TCP的函数shutdown效果展示

news2024/11/18 2:43:49

《TCP关闭的两种方法概述》里边理论基础,下边是列出代码,并且进行实验。
服务端代码graceserver.c的内容如下:

#include "lib/common.h"

static int count;

static void sig_int(int signo) {
    printf("\nreceived %d datagrams\n", count);
    exit(0);
}

int main(int argc, char **argv) {
    int listenfd;
    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERV_PORT);

    int rt1 = bind(listenfd, (struct sockaddr *) &server_addr, sizeof(server_addr));
    if (rt1 < 0) {
        error(1, errno, "bind failed ");
    }

    int rt2 = listen(listenfd, LISTENQ);
    if (rt2 < 0) {
        error(1, errno, "listen failed ");
    }

    signal(SIGINT, sig_int);
    signal(SIGPIPE, SIG_IGN);

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

    if ((connfd = accept(listenfd, (struct sockaddr *) &client_addr, &client_len)) < 0) {
        error(1, errno, "bind failed ");
    }

    char message[MAXLINE];
    count = 0;

    for (;;) {
        int n = read(connfd, message, MAXLINE);
        if (n < 0) {
            error(1, errno, "error read");
        } else if (n == 0) {
            error(1, 0, "client closed \n");
        }
        message[n] = 0;
        printf("received %d bytes: %s\n", n, message);
        count++;

        char send_line[MAXLINE];
        sprintf(send_line, "Hi, %s", message);

        sleep(5);

        int write_nc = send(connfd, send_line, strlen(send_line), 0);
        printf("send bytes: %zu \n", write_nc);
        if (write_nc < 0) {
            error(1, errno, "error write");
        }
    }
}

客户端代码graceclient.c内容如下:

# include "lib/common.h"
# define    MAXLINE     4096

int main(int argc, char **argv) {
    if (argc != 2) {
        error(1, 0, "usage: graceclient <IPaddress>");
    }
    
    int socket_fd;
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET, argv[1], &server_addr.sin_addr);

    socklen_t server_len = sizeof(server_addr);
    int connect_rt = connect(socket_fd, (struct sockaddr *) &server_addr, server_len);
    if (connect_rt < 0) {
        error(1, errno, "connect failed ");
    }

    char send_line[MAXLINE], recv_line[MAXLINE + 1];
    int n;

    fd_set readmask;
    fd_set allreads;

    FD_ZERO(&allreads);
    FD_SET(0, &allreads);
    FD_SET(socket_fd, &allreads);
    for (;;) {
        readmask = allreads;
        int rc = select(socket_fd + 1, &readmask, NULL, NULL, NULL);
        if (rc <= 0)
            error(1, errno, "select failed");
        if (FD_ISSET(socket_fd, &readmask)) {
            n = read(socket_fd, recv_line, MAXLINE);
            if (n < 0) {
                error(1, errno, "read error");
            } else if (n == 0) {
                error(1, 0, "server terminated \n");
            }
            recv_line[n] = 0;
            fputs(recv_line, stdout);
            fputs("\n", stdout);
        }
        if (FD_ISSET(0, &readmask)) {
            if (fgets(send_line, MAXLINE, stdin) != NULL) {
                if (strncmp(send_line, "shutdown", 8) == 0) {
                    FD_CLR(0, &allreads);
                    if (shutdown(socket_fd, 1)) {
                        error(1, errno, "shutdown failed");
                    }
                } else if (strncmp(send_line, "close", 5) == 0) {
                    FD_CLR(0, &allreads);
                    if (close(socket_fd)) {
                        error(1, errno, "close failed");
                    }
                    sleep(6);
                    exit(0);
                } else {
                    int i = strlen(send_line);
                    if (send_line[i - 1] == '\n') {
                        send_line[i - 1] = 0;
                    }

                    printf("now sending %s\n", send_line);
                    size_t rt = write(socket_fd, send_line, strlen(send_line));
                    if (rt < 0) {
                        error(1, errno, "write failed ");
                    }
                    printf("send bytes: %zu \n", rt);
                }

            }
        }

    }

}

代码如上,想要跟我一样编译以后进行测试的话,需要先参考《网络编程实战课程使用Cmake第一次编译程序》进行编译,之后再来验证套接字上的closeshutdown两个函数。

实验一

在其中一个终端,输入./graceserver然后按下一个回车,打开服务器程序。
之后再打开一个终端,输入./graceclient 127.0.0.1然后按下一个回车,打开客户端程序,然后先验证套接字的close函数,快速在5秒内输出data1data2close三个字符串。
在这里插入图片描述
可以看到close函数直接就把客户端套接字的读写两个方向都关闭了。

实验二

在其中一个终端,输入./graceserver然后按下一个回车,打开服务器程序。
之后再打开一个终端,输入./graceclient 127.0.0.1然后按下一个回车,打开客户端程序,然后先验证套接字的close函数,快速在5秒内输出data1data2shutdown三个字符串。
在这里插入图片描述
这里可以看到shutdown只是先把客户端写方向关闭,但是读的方向还打开着,这就是为什么还能接受到服务器端的Hi, data1Hi, data2两个字符串。

此文章为11月Day 11学习笔记,内容来源于极客时间《网络编程实战》。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1196752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让各大运营商都默默流泪的 HTTPS 协议(HTTPS 的加密流程)

文章目录 前言1. 什么是 HTTPS1.1 臭名昭著的 "运营商劫持" 2. 什么是"加密"3. HTTPS 的加密流程3.1 对称加密用对称加密可行吗&#xff1f; 3.2 引入非对称加密用对称加密非对称加密可行吗&#xff1f; 3.3 中间人攻击如何证明浏览器收到的公钥一定是该网…

Linux系统上搭建高可用Kafka集群(使用自带的zookeeper)

本次在CentOS7.6上搭建Kafka集群 Apache Kafka 是一个高吞吐量的分布式消息系统&#xff0c;被广泛应用于大规模数据处理和实时数据管道中。本文将介绍在CentOS操作系统上搭建Kafka集群的过程&#xff0c;以便于构建可靠的消息处理平台。 文件分享&#xff08;KafkaUI、kafka…

matplotlib 创建图和子图

Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件。它能让使用者很轻松地将数据图形化&#xff0c;并且提供多样化的输出格式。这里将会探索 matplotlib 的常见用法。 plt方式是先生成了一个画布&#xff0c;然后在这个画布上隐式的生成一个画图区域来进行画图&#xff1…

提升中小企业效率的不可或缺的企业云盘网盘

相比之大型企业&#xff0c;中小型企业在挑选企业云盘工具更注重灵活性和成本。那么市面上有哪些企业云盘产品更适合中小企业呢&#xff1f; 说起中小企业不能错过的企业云盘网盘&#xff0c;Zoho Workdrive企业云盘绝对榜上有名&#xff01; Zoho Workdrive企业云盘为用户提…

利用Python代码提取shp中每个区域的图像

import geopandas as gpd import rasterio from rasterio.mask import mask import matplotlib.pyplot as plt import numpy as np# 载入shp文件 - 它只包含几何对象 shapefile_path rD:\Desktop\新建文件夹 (3)\01.shp shapes gpd.read_file(shapefile_path)# 打开图像 imag…

杂记杂记杂记

目录 Mybatis分页插件原理&#xff1f; ThreadLocal? 树形表的标记字段是什么&#xff1f;如何查询MySQL树形表&#xff1f; Mybatis的ResultType和ResultMap的区别&#xff1f; #{}和${}有什么区别&#xff1f; 系统如何处理异常&#xff1f; Mybatis分页插件原理&#…

家居美学:将水离子壁炉融入你的现代装饰

当谈及家居装饰和壁炉选择时&#xff0c;水离子雾化壁炉是一个备受瞩目的话题。水离子雾化壁炉的美学价值&#xff0c;还为室内装饰带来全新的维度。它甚至能够激发室内装饰的灵感。 水离子雾化壁炉是现代美学的标志&#xff0c;融合了简洁、线条清晰的设计。这种壁炉常常采用不…

Java性能测试中常用的锁

多线程编程在现代软件开发中扮演着至关重要的角色。它使我们能够有效地利用多核处理器和提高应用程序的性能。然而&#xff0c;多线程编程也伴随着一系列挑战&#xff0c;其中最重要的之一就是处理共享资源的线程安全性。在这个领域&#xff0c;锁&#xff08;Lock&#xff09;…

compile: version “go1.19“ does not match go tool version “go1.18.1“

** 1 安装了新版本的go后 为什么go version 还是旧版本&#xff1f; ** 如果你已经按照上述步骤安装了新版本的 Go&#xff0c;但 go version 命令仍然显示旧版本&#xff0c;可能是因为你的环境变量设置不正确或未正确生效。你可以尝试以下方法来解决问题&#xff1a; 重新…

在PyTorch中使用CUDA, pytorch与cuda不同版本对应安装指南,查看CUDA版本,安装对应版本pytorch

目录 1 查看本机CUDA版本 2 查看对应CUDA的对应pytorch版本安装 3 用pip 安装 4 用conda安装 5 验证安装 在PyTorch中使用CUDA&#xff0c;根据你的具体环境和需求调整版本号&#xff0c;确保安装的PyTorch版本与你的CUDA版本兼容。 在PyTorch中使用CUDA&#xff0c;你需…

品牌滥用申诉

指导 据了解&#xff0c;有以下几种情况可能会出现品牌滥用&#xff1a; 第一种&#xff1a;店铺存在问题 包括但不限于以下问题&#xff1a;店铺绩效中有感叹号、店铺 rating 少于 4.5 分、ODR 超标、被变狗 过、二手货投诉、商标版权专利侵权等。 第二种&#xff1a;品牌授…

深入浅出Python异常处理 - 你所不知道的Python异常

深入浅出Python异常处理 - 你所不知道的Python异常 前言 在Python编程开发中&#xff0c;异常处理扮演者至关重要的角色。合适的异常处理不仅可以提高代码的健壮性&#xff0c;还能增强程序的可读性和可维护性。在Python编程中&#xff0c;有效地管理异常是提高代码质量的关键…

腾讯小程序音视频 TRTC live-pusher 黑屏等各种问题

微信小程序进行音视频开发, 主要会用到live-player live-pusher,这两个媒体组件. 在开发的过程中,会遇到各种各样的问题,其中最直接的就是黑屏问题, 以下就这个问题进行整理. 文档: https://developers.weixin.qq.com/miniprogram/dev/component/live-player.html https://dev…

【CASS精品教程】cass3d加载点云(.ilas和.las)并处理应用

本文讲解cass11.0 3d中将las点云转为ilas加载并进行后续处理。(cass11.0下载与安装) 一、ilas点云格式介绍 点云ilas格式是现今数字化三维模型建模的--种普遍被使用的数据格式,也被称作点云、点集或聚集点。它把地球表面上的物体,比如森林、海洋、河流、山脉等自然物体,以…

AI通义灵码能够帮你写通达信选股公式么?

答案是否定的 先不说语法错误&#xff0c;注释错误&#xff0c;就说AI压根不理解炸板和涨停板&#xff1b; 算了&#xff0c;股票交易AI千万别来掺和&#xff0c;会死的很惨的。

Linux下的调试工具——GDB

GDB 1.什么是GDB GDB 是由 GNU 软件系统社区提供的调试工具&#xff0c;同 GCC 配套组成了一套完整的开发环境&#xff0c;GDB 是 Linux 和许多 类Unix系统的标准开发环境。 一般来说&#xff0c;GDB 主要能够提供以下四个方面的帮助&#xff1a; 启动程序&#xff0c;可以按…

改进YOLOv8:结合ICCV2023|动态蛇形卷积,构建不规则目标识别网络

🔥🔥🔥 提升多尺度、不规则目标检测,创新提升 🔥🔥🔥 🔥🔥🔥 捕捉图像特征和处理复杂图像特征 🔥🔥🔥 👉👉👉: 本专栏包含大量的新设计的创新想法,包含详细的代码和说明,具备有效的创新组合,可以有效应用到改进创新当中 👉👉👉: �…

什么是稳定扩散,它是如何工作的?

推荐基于稳定扩散(stable diffusion) AI 模型开发的自动纹理工具&#xff1a; DreamTexture.js自动纹理化开发包 - NSDT 稳定扩散是潜在扩散模型的一个版本。潜在空间用于获得数据的低维表示的好处。之后&#xff0c;使用扩散模型和添加和去除噪声的方法根据文本生成图像。在接…

《红蓝攻防对抗实战》十.内网穿透之利用DNS协议进行隧道穿透

一.利用DNS协议进行隧道穿透 1.环境配置2.Windows系统下进行DNS隧道穿透利用3.Linux系统下进行DNS隧道穿透利用 前文推荐&#xff1a; 《红蓝攻防对抗实战》一. 隧道穿透技术详解 《红蓝攻防对抗实战》二.内网探测协议出网之TCP/UDP协议探测出网 《红蓝攻防对抗实战》三.内网…

抖音小程序开发:打造高效餐饮团购平台的技术指南

在餐饮行业&#xff0c;通过抖音小程序开发一个高效的团购平台&#xff0c;可以为餐厅提供更广泛的曝光&#xff0c;增加销售机会。本文将从技术角度出发&#xff0c;为您提供一份详细的抖音小程序开发指南&#xff0c;助您打造一流的餐饮团购平台。 一、确定需求和功能 在开…