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

2024-04-17 06:36

本文主要是介绍当全连接队列满了,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族的流类型socketif(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_INETinet_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                                    //侦听队列长度:2extern 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;//进程IDchar buffer[1024];ssize_t size = 0;/***  Step 2 : 建立套接字*/ss = socket(AF_INET,SOCK_STREAM,0);              //创建一个AF_INET族的流类型socketif(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_INETserver_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/bashfor i in {1..100}
do
{./tcpclient &
}
done

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

这篇关于当全连接队列满了,tcp客户端收到服务端RST信令的模拟的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/911044

相关文章

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

SpringKafka错误处理(重试机制与死信队列)

《SpringKafka错误处理(重试机制与死信队列)》SpringKafka提供了全面的错误处理机制,通过灵活的重试策略和死信队列处理,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、Spring Kafka错误处理基础二、配置重试机制三、死信队列实现四、特定异常的处理策略五

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Python3.6连接MySQL的详细步骤

《Python3.6连接MySQL的详细步骤》在现代Web开发和数据处理中,Python与数据库的交互是必不可少的一部分,MySQL作为最流行的开源关系型数据库管理系统之一,与Python的结合可以实... 目录环境准备安装python 3.6安装mysql安装pymysql库连接到MySQL建立连接执行S

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma