当全连接队列满了,tcp客户端收到服务端RST信令的模拟

当tcp服务端全连接队列满了后,并且服务端也不accept取出连接,客户端再次连接时,服务端能够看到SYN_RECV状态。但是客户端看到的是ESTABLISHED状态,所以客户端自认为成功建立了连接,故其写往服务端写数据,发现数据也确实写成功了。
但是后面等到服务端通过ACK+SYN告知客户端重新ACK时,发现此时客户端的业务数据已经到来了,故而认为出了问题,故重置连接。

对应的代码如下:

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define PORT 8888                                     //端口地址:8888
#define SERVER_IP "10.0.0.64"

extern void process_conn_client(int s);

int main(int argc,char *argv[])
{
    int s = 0;                                        //socket描述符
    struct sockaddr_in server_addr;                   //服务器地址结构
    int ret = 0;                                      //返回值
    char buf[1024] = {0};
    int i = 0;
    strcpy(buf, "hello world");
    /**
     *  Step 2 : 建立套接字
     */
    s = socket(AF_INET,SOCK_STREAM,0);                //创建一个AF_INET族的流类型socket
    if(s < 0)                                         //检查是否正常创建socket
    {
        perror("socket error\n");
        exit(EXIT_FAILURE);
    }

    /**
     *  Step 3 : 设置服务器地址
     */
    memset(&server_addr, 0, sizeof(server_addr));          //清零
    server_addr.sin_family = AF_INET;                 //设置地址族为AF_INET
    inet_pton(AF_INET, SERVER_IP, &(server_addr.sin_addr));
    server_addr.sin_port = htons(PORT);               //设置端口号

    /**
     *  Step 4 : 将用户输入的字符串类型的IP地址转为整型
     */
    //inet_pton(AF_INET,argv[1],&server_addr.sin_addr);

    /**
     *  Step 5 : 连接服务器
     */
    ret = connect(s,(struct sockaddr*)&server_addr,sizeof(struct sockaddr));
    if(ret < 0)
    {
        perror("connect error\n");
        printf("errno is %d\n", errno);
        exit(EXIT_FAILURE);
    }
    printf("connect succeed\n");
    //for(;;)
    {
        //sleep(10000000);
        sprintf(buf, "hello world, %d", i);
        i++;

        ret = write(s,buf,strlen(buf)+1);
        if(ret < 0)
        {
            printf("write failed, errno is %d\n", errno);
        }
        ret = read(s, buf, strlen(buf)+1);
        if(ret < 0)
        {
            printf("read failed, errno is %d\n", errno);
        }

    }
    while(1)sleep(10);
    close(s);                                         //关闭连接
}

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>

#define PORT 8888                                    //侦听端口地址:8888
#define BACKLOG 20                                    //侦听队列长度:2

extern void process_conn_server(int s);              //服务器对客户端的处理:读取数据并发送响应字符

int main(int argc,char *argv[])
{
        int ss = 0;                                      //ss = server socket = 服务器socket描述符
    int cs = 0;                                      //cs = client socket = 客户端socket描述符
    struct sockaddr_in server_addr;                  //服务器地址结构
    struct sockaddr_in client_addr;                  //客户端地址结构
    int ret = 0;                                     //返回值
    pid_t pid;
        //进程ID
        char buffer[1024];
        ssize_t size = 0;

    /**
     *  Step 2 : 建立套接字
    */
    ss = socket(AF_INET,SOCK_STREAM,0);              //创建一个AF_INET族的流类型socket
    if(ss < 0)                                       //检查是否正常创建socket
    {
        perror("socket error\n");
        exit(EXIT_FAILURE);
    }
   
    /**
     *  Step 3 : 设置服务器地址
     *  Note:
     *      htonl():将主机数转换成无符号长整型的网络字节顺序
     *      htons():将整型变量从主机字节顺序转变成网络字节顺序
    */
    bzero(&server_addr,sizeof(server_addr));          //清零
    server_addr.sin_family = AF_INET;                 //设置地址族为AF_INET
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //本地地址
        server_addr.sin_port = htons(PORT);               //设置端口号

    /**
     *  Step 4 : 绑定地址结构到套接字描述符
    */
    ret = bind(ss,(struct sockaddr*)&server_addr,sizeof(server_addr));
    if (ret < 0)                                      //出错
    {
        perror("bind error\n");
        exit(EXIT_FAILURE);
    }

    /**
     *  Step 5 : 设置侦听,侦听队列长度为2,可同时处理两个客户端连接请求
    */
    ret = listen(ss,BACKLOG);
    if (ret < 0)                                      //出错
    {
        perror("bind error\n");
        exit(EXIT_FAILURE);
    }

    /**
     *  Step 6 : 主循环过程
    */
    sleep(6000);
    for(;;)
    {
        /* 接收客户端连接 */
        int addrlen = sizeof(struct sockaddr);
        cs = accept(ss,(struct sockaddr*)&client_addr,&addrlen);
        if(cs < 0)                                    //出错
        {
            continue;                                 //结束本次循环
        }
        //sleep(30);

/*
                for(;;)
                {
                        size = read(cs,buffer,1024);                 //从套接字中读取数据放到缓冲区buffer中

                        if(size == 0)                               //没有数据
                        {
                                return;
                        }

                        printf("buffer is %s\n", buffer);
                }
*/



    }
        return 0;
}

客户端通过下面脚本并发投递100个:

#!/bin/bash

for i in {1..100}
do
{
        ./tcpclient &
}
done

最终可以看到客户端的打印情况:
在这里插入图片描述
其中104代表连接被对端重置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM之本地方法栈和程序计数器和堆

本地方法栈 本地方法栈是为虚拟机执行本地方法时提供服务的 JNI&#xff1a;Java Native Interface&#xff0c;通过使用 Java 本地接口程序&#xff0c;可以确保代码在不同的平台上方便移植 不需要进行 GC&#xff0c;与虚拟机栈类似&#xff0c;也是线程私有的&#xff0c;…

C语言--函数递归

目录 1、什么是递归&#xff1f; 1.1 递归的思想 1.2 递归的限制条件 2. 递归举例 2.1 举例1&#xff1a;求n的阶乘 2.2 举例2&#xff1a;顺序打印⼀个整数的每⼀位 3. 递归与迭代 扩展学习&#xff1a; 早上好&#xff0c;下午好&#xff0c;晚上好 1、什么是递归&…

【鸿蒙开发】生命周期

1. UIAbility组件生命周期 UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态。 UIAbility生命周期状态 1.1 Create状态 Create状态为在应用加载过程中&#xff0c;UIAbility实例创建完成时触发&#xff0c;系统会调用onCreate()回调。可以在该回调中…

gcc常用命令指南(更新中...)

笔记为gcc常用命令指南&#xff08;自用&#xff09;&#xff0c;用到啥方法就具体研究一下&#xff0c;更新进去... 编译过程的分布执行 64位系统生成32位汇编代码 gcc -m32 test.c -o test -m32用于生成32位汇编语言

大学生前端学习第一天:了解前端

引言&#xff1a; 哈喽&#xff0c;各位大学生们&#xff0c;大家好呀&#xff0c;在本篇博客&#xff0c;我们将引入一个新的板块学习&#xff0c;那就是前端&#xff0c;关于前端&#xff0c;GPT是这样描述的&#xff1a;前端通常指的是Web开发中用户界面的部分&#xff0c;…

【读论文】【泛读】三篇生成式自动驾驶场景生成: Bevstreet, DisCoScene, BerfScene

文章目录 1. Street-View Image Generation from a Bird’s-Eye View Layout1.1 Problem introduction1.2 Why1.3 How1.4 My takeaway 2. DisCoScene: Spatially Disentangled Generative Radiance Fields for Controllable 3D-aware Scene Synthesis2.1 What2.2 Why2.3 How2.4…

解决QtCreator不能同时运行多个程序的方法

当我们运行QtCreator代码的时候&#xff0c;往往一个代码&#xff0c;可能需要打开好几个运行&#xff0c;但是会出现的情况就是&#xff0c;如果打开了一个界面&#xff0c;当我么再运行的时候&#xff0c;第一个界面就没有了&#xff0c;而且可能会出现终端报错的情况&#x…

虚拟环境下的Pip引用外部环境的解决方法

当你使用新创建的虚拟环境时&#xff0c;测试pip list却显示了一堆自己没有的功能包&#xff0c;这是因为你的环境错乱了&#xff0c;废话不多说直接上解决办法。 设置-》高级系统设置 环境变量 在系统变量部分&#xff0c;Anaconda要求前边没有其余的python环境路径。

开源全方位运维监控工具:HertzBeat

HertzBeat&#xff1a;实时监控系统性能&#xff0c;精准预警保障业务稳定- 精选真开源&#xff0c;释放新价值。 概览 HertzBeat是一款深受广大开发者喜爱的开源实时监控解决方案。它以其简洁直观的设计理念和免安装Agent的特性&#xff0c;实现了对各类服务器、数据库及应用…

vagrant 安装虚拟机,docker, k8s

第一步&#xff1a;安装虚拟机 1、安装 vagrant 本机是 mac, 但是这一步不影响&#xff0c;找对应操作系统的安装方式就行了。 vagrant 下载地址 brew install vagrant 2、下载 VirtualBox 虚拟机 VirtualBox 下载地址 找到对应系统下载&#xff0c;安装就可以。 尽量把…

项目中,如何写 readme.md 文件 | 写项目总结

tips&#xff1a;注意写 1. readme文件&#xff1a;①项目文档&#xff08;项目需求和设计文档、项目系统架构和技术文档、接口文档&#xff09;、②项目结构、③启动项目。具体结构见下文。 2. 项目总结&#xff1a;技术栈、描述、主要工作&#xff01;&#xff01;需求及功…

Rust面试宝典第4题:打家劫舍

题目 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统。如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金额的非负整…

多线程传参以及线程的优缺点

进程是资源分配的基本单位 线程是调度的基本单位 笼统来说&#xff0c;线程有以下优点&#xff1a; 创建一个新线程的代价要比创建一个新进程小得多 与进程之间的切换相比&#xff0c;线程之间的切换需要操作系统做的工作要少很多 线程占用的资源要比进程少很多 能充分利用多…

Pytorch手撸Attention

Pytorch手撸Attention 注释写的很详细了&#xff0c;对照着公式比较下更好理解&#xff0c;可以参考一下知乎的文章 注意力机制 import torch import torch.nn as nn import torch.nn.functional as Fclass SelfAttention(nn.Module):def __init__(self, embed_size):super(S…

Sy-linux下常用的网络命令linux network commands

linux下的网络命令非常强大&#xff0c;这里根据教材需要&#xff0c;列出来常用的网络命令和场景实例&#xff0c;供参考。 一、命令列表&#xff1a; Command Description ip Manipulating routing to assigning and configuring network parameters traceroute Identi…

【Java】通过poi给word首页添加水印图片

背景&#xff1a; poi并没有提供直接插入水印图片的方法&#xff0c;目前需要再word的首页插入一张水印图片&#xff0c;于是就需要通过另一种方式&#xff0c;插入透明图片&#xff08;png格式&#xff09;并将图片设置为“浮于文字上方”的方式实现该需求。 所需jar&#xf…

Linux解压4GB以上zip文件

Linux使用unzip解压大于4GB文件&#xff0c;会出现以下错误&#xff1a; 解决方法 安装p7zip yum -y install p7zip执行命令&#xff1a; 7za x MSRVTT.zip

Spark-机器学习(2)特征工程之特征提取

在之前的文章中&#xff0c;我们了解我们的机器学习&#xff0c;了解我们spark机器学习中的MLIib算法库&#xff0c;知道它大概的模型&#xff0c;熟悉并认识它。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&a…

HackMyVM-Connection

目录 信息收集 arp nmap WEB web信息收集 dirsearch smbclient put shell 提权 系统信息收集 suid gdb提权 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.115 S…

js打印页面源码 ,打印选取的容器里的内容,打印指定内容

js打印页面源码 &#xff0c;打印选取的容器里的内容&#xff0c;打印指定内容 效果 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge&…
最新文章