Linux网络编程二(TCP三次握手、四次挥手、TCP滑动窗口、MSS、TCP状态转换、多进程/多线程服务器实现)

TCP三次握手

TCP三次握手(TCP three-way handshake)是TCP协议建立可靠连接的过程,确保客户端和服务器之间可以进行可靠的通信。下面是TCP三次握手的详细过程:
假设客户端为A,服务器为B
1、第一次握手(SYN=1,seq=500)
A向B发送一个带有SYN标志位的数据包,表示A请求建立连接。SYN标志位为1表示这是一个连接请求数据包,500是A随机选择的初始序列号。
2、第二次握手(SYN=1,ACK=1,ack=500+1,seq=800):
B接收到A发送的连接请求后,会向A回复一个数据包。该数据包中,SYN和ACK标志位都被设置为1。ACK=1表示B确认收到了A的连接请求,ack字段的值为A的初始序列号加1,表明B期望下一个收到的序列号是A初始序列号加1。seq字段800是B随机选择的初始序列号。
3、第三次握手(ACK=1,ack=800+1):
A收到B的回复后,检查ACK标志位是否为1,以及ack字段的值是否为B的初始序列号加1。如果正确,A会向B发送一个确认数据包。在该数据包中,ACK标志位被设置为1,表示A确认收到了B的回复。ack字段的值是B的初始序列号加1,表明A期望下一个收到的序列号是B初始序列号加1。
完成这三次握手后,TCP连接就建立成功,A和B之间可以开始传输数据。连接的状态变为已建立(ESTABLISHED)。
三次握手是操作系统内核(Kernel)的TCP协议栈负责处理。用户层的表现:服务器端是accept(),客户端是connect(),其这两个函数成功执行并返回了。

TCP四次挥手

TCP四次挥手(TCP four-way handshake)是TCP连接的关闭过程,用于在客户端和服务器之间终止一个已建立的连接。与TCP三次握手不同,四次挥手需要进行四个步骤来关闭连接,以确保数据传输的完整性和可靠性。
1、客户端向服务器发送连接释放请求(FIN)的数据包。
客户端希望关闭连接,因此发送一个带有FIN标志位的数据包,FIN=1表示连接释放请求。设置序列号为seq=501。
2、服务器接收到客户端的连接释放请求后,回复确认连接释放(ACK)的数据包。
服务器收到客户端的FIN后,发送一个带有ACK标志位的数据包,ACK=1,ack 502表示确认收到客户端的连接释放请求。
3、服务器向客户端发送连接释放请求(FIN)的数据包。
服务器希望关闭连接,因此发送一个带有FIN标志位的数据包,FIN=1表示连接释放请求。设置序列号为seq=701。
4、客户端接收到服务器的连接释放请求后,回复确认连接释放(ACK)的数据包。
客户端收到服务器的FIN后,发送一个带有ACK标志位(这个不是数据,是控制报文),ACK=1,ack 702表示确认收到服务器的连接释放请求。
在发送完ACK后,客户端等待一段时间,确保服务器收到了ACK,然后完全关闭连接。
自创

TCP滑动窗口

TCP滑动窗口是TCP协议中的一个重要概念,用于实现流量控制和可靠性传输。滑动窗口机制允许发送方和接收方在数据传输过程中动态调整可发送和可接收的数据量,从而适应不同的网络条件和接收方的处理能力。每次通信时,接收方利用win(4096)告知发送方缓冲区剩余大小。
MSS(Maximum Segment Size)是指TCP数据包中的最大有效载荷大小,它表示在TCP协议中一次性发送的最大数据量(即数据包中的有效数据部分,不包括TCP头部和IP头部)。
在TCP连接建立时,通过TCP三次握手的过程中,双方会交换彼此的MSS值,然后根据两端通信的网络链路的MTU大小进行协商,确定实际使用的MSS。

MSS = 1500 - 20 (TCP头部) - 20 (IP头部) = 1460 字节

这意味着在该TCP连接中,一次可以发送的最大有效数据量为1460字节,超过这个大小的数据将被拆分成多个TCP数据包进行传输。
MSS的设置对于TCP性能和网络吞吐量很重要。合理设置MSS可以避免网络分段和数据重组,提高数据传输效率,特别是在一些高延迟、低带宽的网络环境中。

TCP状态时序图

使用命令查看状态

netstat -aptn | grep 端口号  #查看tcp端口
netstat -apn | grep 端口号  #查看tcp、udp端口

1、主动发起连接请求端
CLOSE----发送 SYN—SYN_SEND—接收 ACK、SYN—发送 ACK-ESTABLISHED(数据通信态)
2、主动关闭连接请求端
ESTABLISHED(数据通信态)—发送 FIN—FIN_WAIT_1 --接收 ACK --FIN_WAIT_2(半关闭)—接收对端发送 FIN—FIN_WAIT_2(半关闭)—回发ACK–TIME_WAIT(只有主动关闭连接方,会经历该状态)—等2MSL时长—CLOSE
3、被动接收连接请求端
CLOSE—LISTEN—接收 SYN—LISTEN—发送 ACK、SYN—SYN_RCVD—接收ACK—ESTABLISHED(数据通信态)
4、被动关闭连接请求端
ESTABLISHED(数据通信态)—接收 FIN —ESTABLISHED(数据通信态)— 发送ACK — CLOSE_WAIT(说明对端【主动关闭连接端】处于FIN_WAIT_2(半关闭)状态—发送FIN —LAST_ACK—接收ACK—CLOSE
重点:ESTABLISHED(数据通信态)、FIN_WAIT_2、CLOSE_WAIT、TIME_WAIT(2MSL).
在这里插入图片描述

先启动服务器,只有LISTEN状态。
在这里插入图片描述
启动客户端,此时三次握手建立完成,进入ESTABLISHED(数据通信态)。
在这里插入图片描述
尝试关闭一个客户端,此时该客户端进入TIME_WAIT状态。
在这里插入图片描述
服务器先主动关闭,服务器进入FIN_WAIT_2(半关闭)状态。客户端进入CLOSE_WAIT状态。
在这里插入图片描述
此时迅速关闭客户端,客户端处于TIME_WAIT状态。
在这里插入图片描述
提示:#include "wrap.h"错误处理函数,已经封装
链接://https://blog.csdn.net/qq_45009309/article/details/131813756?spm=1001.2014.3001.5501

多进程并发服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <pthread.h>
#include <signal.h>
#include <sys/wait.h>
#include "wrap.h"				//错误处理函数,已经封装//https://blog.csdn.net/qq_45009309/article/details/131813756?spm=1001.2014.3001.5501#define SRV_PORT 9999void catch_child(int signum)		//回调函数 内核操作 产生信号后进来
{while(waitpid(0, NULL, WNOHANG) > 0);	 //非阻塞回收子进程//循环回收是因为可能产生多个子进程死亡return ;				
}int main(int argc, char* argv[])
{int lfd, cfd;								pid_t pid;int ret;char buf[BUFSIZ];struct sockaddr_in srv_addr, clt_addr;socklen_t clt_addr_len;//memset(&srv_addr, 0, sizeof(srv_addr));				//地址结构清零bzero(&srv_addr, sizeof(srv_addr));srv_addr.sin_family = AF_INET;							srv_addr.sin_port = htons(SRV_PORT);srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);lfd = Socket(AF_INET, SOCK_STREAM, 0);		//创建套接字 返回用于监听的文件描述符Bind(lfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));	//绑定服务器IP+地址Listen(lfd, 128);							//设置监听上线clt_addr_len = sizeof(clt_addr);while (1) {cfd = Accept(lfd, (struct sockaddr*)&clt_addr, &clt_addr_len);	//返回用于双方通信的文件描述符pid = fork();							//创建子进程if (pid < 0) {perr_exit("fork error");}else if (pid == 0) {close(lfd);break;}else {									//父进程使用信号捕捉回收子进程struct sigaction act;act.sa_handler = catch_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;ret = sigaction(SIGCHLD, &act, NULL);if (ret != 0) {perr_exit("sigaction error");}close(cfd);continue;}}if (pid == 0) {								//子进程实现读写功能for (;;) {ret = Read(cfd, buf, sizeof(buf));for (int i = 0; i < ret; i++) {buf[i] = toupper(buf[i]);}write(cfd, buf, ret);write(STDOUT_FILENO, buf, ret);		//实现大小写转换功能if (ret == 0) {close(cfd);exit(1);}}}return 0;
}

在这里插入图片描述

多线程并发服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <pthread.h>
#include <signal.h>
#include <sys/wait.h>
#include "wrap.h"				//错误处理函数,已经封装//https://blog.csdn.net/qq_45009309/article/details/131813756?spm=1001.2014.3001.5501#define MAXLINE 8192
#define SERV_PORT 8000struct s_info {							//定义一个结构体,将地址结构跟cfd捆绑struct sockaddr_in cliaddr;		int connfd;
};void* do_work(void* arg)				//子线程主调函数
{int n, i;struct s_info* ts = (struct s_info*)arg;char buf[MAXLINE];char str[INET_ADDRSTRLEN];			//16while (1) {n = Read(ts->connfd, buf, MAXLINE);if (n == 0) {printf("the client %d closed...\n", ts->connfd);break;}printf("received from %s at PORT %d\n",			//打印客户端IP+端口inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),ntohs((*ts).cliaddr.sin_port));for (i = 0; i < n; i++)buf[i] = toupper(buf[i]);Write(STDOUT_FILENO, buf, n);Write(ts->connfd, buf, n);					//回写到客户端}Close(ts->connfd);return (void*)0;
}int main(int argc, char* argv[])
{struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;pthread_t tid;struct s_info ts[256];		//创建结构体数组int i = 0;listenfd = Socket(AF_INET, SOCK_STREAM, 0);			//创建一个socket,得到lfdbzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SERV_PORT);				//指定端口号servaddr.sin_addr.s_addr = htonl(INADDR_ANY);		//指定本地任意IPBind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));	//绑定Listen(listenfd, 128);printf("Accepting client connect...\n");while (1) {cliaddr_len = sizeof(cliaddr);connfd = Accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len);		//阻塞监听客户端链接请求ts[i].cliaddr = cliaddr;ts[i].connfd = connfd;pthread_create(&tid, NULL, do_work, (void*)&ts[i]);pthread_detach(tid);							//子线程分离,防止僵尸线程产生i++;}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 每日一题 PTA 10.28 day6

1.求奇数分之一序列前N项和 本题要求编写程序&#xff0c;计算序列 1 1 / 3 1 / 5 ... 的前N项之和。 输入格式 : 输入在一行中给出一个正整数N。 输出格式 : 在一行中按照“sum S”的格式输出部分和的值S&#xff0c;精确到小数点后6位。题目保证计算结果不超过双精度范围…

python,pandas ,openpyxl提取excel特定数据,合并单元格合并列,设置表格格式,设置字体颜色,

python&#xff0c;pandas &#xff0c;openpyxl提取excel特定数据&#xff0c;合并单元格合并列&#xff0c;设置表格格式&#xff0c;设置字体颜色&#xff0c; 代码 import osimport numpy import pandas as pd import openpyxl from openpyxl.styles import Font from op…

SQL Delete 语句(删除表中的记录)

SQL DELETE 语句 DELETE语句用于删除表中现有记录。 SQL DELETE 语法 DELETE FROM table_name WHERE condition; 请注意删除表格中的记录时要小心&#xff01;注意SQL DELETE 语句中的 WHERE 子句&#xff01; WHERE子句指定需要删除哪些记录。如果省略了WHERE子句&#xff…

基于SpringBoot+Vue的服装销售系统

基于SpringBootVue的服装销售平台的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 我的订单 登录界面 管理员界面 摘要 基于SpringBoot和Vue的服装销售系统…

Java SE 学习笔记(十四)—— IO流(2)

目录 1 字节流1.1 字节流写数据1.1.1 创建字节输出流对象1.1.2 字节流写数据 1.2 字节流读数据1.2.1 创建字节输入流对象1.2.2 字节流读数据 1.3 字节流复制文件1.4 流的刷新与关闭1.5 资源释放方式1.5.1 try-catch-finally1.5.2 try-with-resource 2 字符流2.1 字符流概述2.2 …

C#__简单了解XML文档

/* XML(可扩展标记语言)&#xff1a;用于传输和存储数据 XML文档&#xff1a;树结构&#xff1b;包含根元素 XML元素&#xff1a;从开始标签到结束标签的部分 XML语法规则&#xff1a; 1、所有XML元素都必须有结束标签 …

微信小程序vue+uniapp旅游景点门票预订系统 名胜风景推荐系统

与此同时越来越多的旅游公司建立了自己的基于微信小程序的名胜风景推荐平台&#xff0c;管理员通过网站可以添加用户、景点分类、景点信息、在线预订、最新推荐&#xff0c;用户可以对景点信息进行在线预订&#xff0c;以及开展电子商务等。互联网的世界里蕴藏无限生机&#xf…

仓库管理系统源代码集合,带图片展示和网站演示

目录 1、ModernWMS2、GreaterWMS3、kopSoftWMS4、SwebWMS5、若依wms6、jeewms 1、ModernWMS 体验地址&#xff1a;https://wmsonline.ikeyly.com 简易完整的仓库管理系统 该库存管理系统是&#xff0c;我们从多年ERP系统研发中总结出来的一套针对小型物流仓储供应链流程。 简…

Spring cloud教程Gateway服务网关

Spring cloud教程|Gateway服务网关 写在前面的话&#xff1a; 本笔记在参考网上视频以及博客的基础上&#xff0c;只做个人学习笔记&#xff0c;如有侵权&#xff0c;请联系删除&#xff0c;谢谢&#xff01; Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;…

【vtk学习笔记1】编译安装vtk9.2.6,运行官方例子

一、编译安装vtk-9.2.6 1. 下载VTK。推荐从github下载。目前从VTK官网只能下载最新的RC版或者以前的老版本&#xff0c;我是在github上下载的vtk9.2.6 tag版本。 2. 用Cmake-gui配置Visual Studio工程。主要注意配置VTK安装的路径、是否支持QT&#xff0c;需要的话正确配置Qt5…

JavaWeb 怎么在servlet向页面输出Html元素?

service()方法里面的方法体&#xff1a; resp.setContentType("text/html;charsetutf-8");//获得输出流PrintWriter对象PrintWriter outresp.getWriter();out.println("<html>");out.println("<head><title>a servlet</title>…

python自动化测试(六):唯品会商品搜索-练习

目录 一、配置代码 二、操作 2.1 输入框“运动鞋” 2.2 点击搜索按钮 2.3 选择品牌 2.4 选择主款 2.5 适用性别 2.6 选择尺码 2.7 选择商品&#xff1a;&#xff08;通过css的属性去匹配&#xff09; 2.8 点击配送地址选项框 一、配置代码 # codingutf-8 from selen…

RPA除了和OCR、NLP技术结合,还能和什么技术结合?

鉴于业内现在也经常把RPA称为数字员工&#xff0c;就虚拟一个人的形象来解答吧。 首先是头部&#xff0c;实现人的“听看说想”能力&#xff1a; 听&#xff1a;ASR&#xff08;语音识别技术&#xff09;&#xff0c;主要用于听取和理解语音输入&#xff0c;让RPA能处理语音数…

大数据Flink(一百零三):SQL 表值聚合函数(Table Aggregate Function)

文章目录 SQL 表值聚合函数(Table Aggregate Function) SQL 表值聚合函数(Table Aggregate Function) Python UDTAF,即 Python TableAggregateFunction。Python UDTAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等,与…

leetcode经典面试150题---4.删除有序数组中的重复项II

目录 题目描述 前置知识 代码 方法一 双指针 思路 图解 实现 复杂度 题目描述 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&…

泰州市旅游景点门票预订管理系统 vue+uniapp微信小程序

本文从管理员、用户的功能要求出发&#xff0c;泰州市旅游景点管理小程序中的功能模块主要是实现用户、景点类型、景区信息、门票预定。经过认真细致的研究&#xff0c;精心准备和规划&#xff0c;最后测试成功&#xff0c;系统可以正常使用。分析功能调整与泰州市旅游景点管理…

java代码审计-不安全的配置-Tomcat任意文件写入(CVE-2017-12615)

Tomcat任意文件写入&#xff08;CVE-2017-12615&#xff09; 影响范围&#xff1a;Apache Tomcat 7.0.0 - 7.0.79 (windows环境) 当 Tomcat 运行在 Windows 操作系统时&#xff0c;且启用了 HTTP PUT 请求方法&#xff08;例如&#xff0c;将 readonly 初始化参数由默认值设置…

centos7 部署 Flink

1. 准备 安装的前提是虚拟机里已安装了jdk 去官网下载 Flink 所有版本下载地址&#xff1a;https://archive.apache.org/dist/flink/ 找到下图的安装包&#xff0c;下载即可 下载完后&#xff0c;将其上传至虚拟机的某个地方&#xff0c;本人将其放在 /home/flink/ 下 解压…

帮你快速解锁忘记密码手机的十个工具

将手机解锁到任时候都会让人感觉呼吸新鲜空气。这就像摆脱无形的锁链一样&#xff0c;让您有权选择并避免那些讨厌的限制。但如何解锁手机呢&#xff1f;这就是解锁软件发挥作用的地方。这些方便的工具可以帮助您摆脱束缚并打开一个充满可能性的世界。 解锁手机的合法性 现在&…

分布式理论和分布式锁知识点总结

文章目录 (一) 分布式理论算法和协议1&#xff09;CAP理论总结 2&#xff09;BASE理论BASE 理论的核心思想基本可用软状态最终一致性 3&#xff09;Paxos算法Basic Paxos 算法4&#xff09; Raft算法1 拜占庭将军 5&#xff09;Gossip协议 (二) 分布式锁分布式锁应该具备哪些条…