webserver|4.23-4.24 TCP状态转换、半关闭、端口复用

news2024/11/25 20:55:09

4.23 TCP状态转换

四次挥手:

 

 

 

 另一种状态图:

红色实线:客户端

绿色虚线:服务端状态转变

 

4.24 半关闭、端口复用

半关闭

 基本就是一边closed,另一边还没有closed

一边一旦closed之后就不能再向另一方传数据(ACK信号不算要传的数据)。

端口复用:

 recv是socket通信特有的函数,用来接收信息。

 这里作者直接运行了两个文件来观察三次握手和四次挥手(尤其是四次挥手时状态的转变)

假如服务器和客户端成功通信之后,断开了服务器sever,短时间内想再运行./server

是不可能的:

 

 

原因是:

 服务端当前处于FIN_WAIT_2状态。相当于

过了这段时间后就可以了。

 有时候服务器重启后,有2ml的时间服务器无法绑定,为了解决这个问题,要用到端口复用:

 

 则服务器端代码:

#include <stdio.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {

    // 创建socket
    int lfd = socket(PF_INET, SOCK_STREAM, 0);

    if(lfd == -1) {
        perror("socket");
        return -1;
    }

    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;
    saddr.sin_port = htons(9999);
    
    //int optval = 1;
    //setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    //端口复用,在bind之前
    int optval = 1;//1代表可以复用,2代表不可以复用
    setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));

    // 绑定
    int ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
    if(ret == -1) {
        perror("bind");
        return -1;
    }

    // 监听
    ret = listen(lfd, 8);
    if(ret == -1) {
        perror("listen");
        return -1;
    }

    // 接收客户端连接
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);
    int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);
    if(cfd == -1) {
        perror("accpet");
        return -1;
    }

    // 获取客户端信息
    char cliIp[16];
    inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, cliIp, sizeof(cliIp));
    unsigned short cliPort = ntohs(cliaddr.sin_port);

    // 输出客户端的信息
    printf("client's ip is %s, and port is %d\n", cliIp, cliPort );

    // 接收客户端发来的数据
    char recvBuf[1024] = {0};
    while(1) {
        int len = recv(cfd, recvBuf, sizeof(recvBuf), 0);
        if(len == -1) {
            perror("recv");
            return -1;
        } else if(len == 0) {
            printf("客户端已经断开连接...\n");
            break;
        } else if(len > 0) {
            printf("read buf = %s\n", recvBuf);
        }

        // 小写转大写
        for(int i = 0; i < len; ++i) {
            recvBuf[i] = toupper(recvBuf[i]);
        }

        printf("after buf = %s\n", recvBuf);

        // 大写字符串发给客户端
        ret = send(cfd, recvBuf, strlen(recvBuf) + 1, 0);
        if(ret == -1) {
            perror("send");
            return -1;
        }
    }
    
    close(cfd);
    close(lfd);

    return 0;
}

客户端:

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main() {

    // 创建socket
    int fd = socket(PF_INET, SOCK_STREAM, 0);
    if(fd == -1) {
        perror("socket");
        return -1;
    }

    struct sockaddr_in seraddr;
    inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr);
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(9999);

    // 连接服务器
    int ret = connect(fd, (struct sockaddr *)&seraddr, sizeof(seraddr));

    if(ret == -1){
        perror("connect");
        return -1;
    }

    while(1) {
        char sendBuf[1024] = {0};
        fgets(sendBuf, sizeof(sendBuf), stdin);

        write(fd, sendBuf, strlen(sendBuf) + 1);

        // 接收
        int len = read(fd, sendBuf, sizeof(sendBuf));
        if(len == -1) {
            perror("read");
            return -1;
        }else if(len > 0) {
            printf("read buf = %s\n", sendBuf);
        } else {
            printf("服务器已经断开连接...\n");
            break;
        }
    }

    close(fd);

    return 0;
}

 4.25 IO多路复用---------极其重点

这里有个链接动图:登录—专业IT笔试面试备考平台_牛客网

方便理解建议看动图。

 所谓读和写,对两个socket之间进行通信时,都各自有各自的读缓冲区和写缓冲区。

把这两个方框看成server和client,每个端都有读缓冲区和写缓冲区。

之前只能遍历一个个文件描述符:

I/O 多路复用使得程序能同时监听多个文件描述符,能够提高程序的性能,Linux 下实现 I/O 多路复用的系统调用主要有 select、poll 和 epoll。

几种常见的io模型

一、

 在等待的过程中,cpu的使用权交给了其他人。

这两种都是:

 二:

非阻塞模型,即使accept不到也不会阻塞,缺点是很可能10000个客户端其中9999个都没有用,遍历是浪费的。

 底层使用二进制位,有数据就会置为1.

 

 

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

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

相关文章

异常检测专栏(三)传统的异常检测算法——上

前言 在上一篇推文中&#xff0c;我们简要介绍了异常检测常用的几种数据集如ImageNet、CIFAR10/CIFAR100、MNIST等。接下来&#xff0c;我们将基于传统的异常检测算法分为上、下两部分&#xff0c;逐一介绍不同类别的方法。 本教程禁止转载。同时&#xff0c;本教程来自知识星球…

matlab将RGB图像在HSI空间去噪

思路与代码 RGB 转换为 HSI 的计算步骤如下&#xff1a; 首先归一化三通道值 &#xff1a; r R R G B r \frac{R}{RGB} rRGBR​ g G R G B g \frac{G}{RGB} gRGBG​ b B R G B b \frac{B}{RGB} bRGBB​ 接下来&#xff0c;计算 HSI 图像的亮度 I I I&#xf…

(转载)从0开始学matlab(第3天)—子数组

你可以选择和使用一个 MATLAB 函数的子集&#xff0c;好像他们是独立的数组一样。在数组名后面加括号&#xff0c;括号里面是所有要选择的元素的下标&#xff0c;这样就能选择这个函数的子集了。例如&#xff0c;假设定义了一个数组 arr1 如下 arr1[1.1 -2.2 3.3 -4.4 5.5] 那…

yolov5 实例分割 jason标注格式转换 训练自己的数据集

目录 一、coco128-seg数据集分析 1、配置文件 coco128-seg.yaml 2、coco128-seg数据集 二、自己用anylabeling标注获得的json文件 三、json文件转coco128-seg格式 四、实例分割训练 1、修改数据配置文件 coco128-seg.yaml 2、训练 一、coco128-seg数据集分析 这个博客中有…

5。STM32裸机开发(3)

嵌入式软件开发学习过程记录&#xff0c;本部分结合本人的学习经验撰写&#xff0c;系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维&#xff0c;为RTOS做铺垫&#xff08;本部分基于库函数版实现&#xff09;&#xff0c;如有不足之处&#xff0c;敬请批评指正。 &…

【探索SpringCloud】服务发现

前言 今天&#xff0c;我们来聊聊SpringCloud服务发现。主要有如下几个议题&#xff1a; 一、服务发现的概念与方案&#xff1b;二、SpringCloud是如何与各个服务注册厂商进行集成的。 服务发现 在微服务架构中&#xff0c;我们不可避免的需要通过服务间的调用来完成系统功能…

Fourier分析入门——第1章——数学预备知识

第 1 章 学习Fourier分析的数学预备知识 目录 第 1 章 学习Fourier分析的数学预备知识 1.1 引言 1.2 几何和代数的一些相关概念的回顾 1.2.1 标量运算(scalar arithmetic) 1.2.2 向量运算(vector arithmetic) 1.2.3 向量乘法(vector multiplication) 1.2.4 向量长度 …

设计模式(java)-观察者模式

1. 简介 观察者模式&#xff0c;行为型设计模式。观察者模式在实际项目实践中&#xff0c;是一种使用较频繁的设计模式&#xff0c;它主要解决的是信息同步的问题&#xff0c;当多个对象需要从同一个主题中得到自身所需要的信息或状态&#xff0c;并通过这些信息或状态做出相应…

以太网外设ETH

1. 概述 近几年&#xff0c;项目需要&#xff0c;在多款单片机上使用了以太网外设。 本文为阶段知识整理&#xff0c;查缺补漏&#xff0c;方便以后再次遇到相关任务时&#xff0c;可以游刃有余的完成工作。 1.1 修改时间 2023年5月6日创建本文。包含STM32的ETH外设。2023年…

利用CNN对车牌进行智能识别(python代码,解压缩后直接运行)

1.代码流程 该段代码主要利用卷积神经网络&#xff08;CNN&#xff09;来识别车牌。下面是代码的主要流程&#xff1a; 导入所需的库和模块&#xff0c;包括matplotlib、numpy、cv2、tensorflow等。 加载用于检测车牌的级联分类器&#xff08;cascade classifier&#xff09;…

可见光遥感目标检测(一)任务概要介绍

前言 本篇开始对遥感图像的目标检测进行介绍&#xff0c;介绍了其目标前景、数据集以及评价指标。 本教程禁止转载。同时&#xff0c;本教程来自知识星球【CV技术指南】更多技术教程&#xff0c;可加入星球学习。 Transformer、目标检测、语义分割交流群 欢迎关注公众号CV技…

机器学习13(正则化)

文章目录 简介正则化经验风险和结构风险过拟合正则化建模策略 逻辑回归逻辑回归评估器 练习评估器训练与过拟合实验评估器的手动调参 简介 这一节详细探讨关于正则化的相关内容&#xff0c;并就 sklearn 中逻辑回归&#xff08;评估器&#xff09;的参数进行详细解释由于 skle…

javaweb项目实战之myBlog

项目简介 技术栈&#xff1a; Java Mysql Html Ajax Css JS Json 项目说明 &#xff1a;项目使用maven创建&#xff0c;使用MVC架构模式 表示层&#xff1a;通俗讲就是展现给用户的界面和控制器层Servlet&#xff0c;接受请求、封装数据、调用业务 逻辑层&#xff0c;响…

libevent高并发网络编程 - 05_libevent实现http客户端

文章目录 1 http客户端相关的APIevhttp_uri_parse()evhttp_uri_get_scheme()evhttp_uri_get_port()evhttp_uri_get_host()evhttp_uri_get_path()evhttp_uri_get_query()evhttp_connection_base_bufferevent_new()evhttp_request_new()evhttp_make_request()evhttp_request_get_…

刷题刷题,开心

一先来每日一题 在一个仓库里&#xff0c;有一排条形码&#xff0c;其中第 i 个条形码为 barcodes[i]。 请你重新排列这些条形码&#xff0c;使其中任意两个相邻的条形码不能相等。 你可以返回任何满足该要求的答案&#xff0c;此题保证存在答案。 示例 1&#xff1a; 输入&…

基于html+css图展示59

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Prompt learning 教学[最终篇]:Chatgpt使用场景推荐、优秀学习资料推荐、AI工具推荐

Prompt learning 教学[最终篇]&#xff1a;Chatgpt使用场景推荐、优秀学习资料推荐、AI工具推荐 1.chatgpt使用场景推荐 各位应该在各种平台看到不少可以尝试使用的场景&#xff0c;我这里仅收录&#xff1a; 有意思的场景&#xff1a;一般比较垂直或者小众&#xff0c;或者出…

CobaltStrike项目实战

环境介绍 模拟内网有三台机器&#xff1a;WEB、PC和DC。 WEB服务器有两个网络适配器&#xff0c;适配器1处于NAT模式用于连接外网&#xff0c;适配器2用于内网。 PC和WEB服务器一样&#xff0c;有两个适配器&#xff0c;能够同时访问外网和内网&#xff1b;DC作为域控制器&…

神经网络的训练过程、常见的训练算法、如何避免过拟合

神经网络的训练是深度学习中的核心问题之一。神经网络的训练过程是指通过输入训练数据&#xff0c;不断调整神经网络的参数&#xff0c;使其输出结果更加接近于实际值的过程。本文将介绍神经网络的训练过程、常见的训练算法以及如何避免过拟合等问题。 神经网络的训练过程 神…

henan Problem E. 矩阵游戏

hunan Problem E. 矩阵游戏 Attachments - 2023 CCPC Henan Provincial Collegiate Programming Contest - Codeforces 思路&#xff1a; 我们考虑用dp,定义f[i][j][k],代表从1,1走到i,j并且使用k次变换操作能够获得的最大 价值&#xff0c;那么类似于01背包&#xff0c;接下…