【网络编程】第四章 网络套接字(守护进程+TCP英译汉+TCP通协议讯流程+TCP和UDP对比)

news2025/6/19 6:10:21

🏆个人主页:企鹅不叫的博客

​ 🌈专栏

  • C语言初阶和进阶
  • C项目
  • Leetcode刷题
  • 初阶数据结构与算法
  • C++初阶和进阶
  • 《深入理解计算机操作系统》
  • 《高质量C/C++编程》
  • Linux

⭐️ 博主码云gitee链接:代码仓库地址

⚡若有帮助可以【关注+点赞+收藏】,大家一起进步!

💙系列文章💙

【网络编程】第一章 网络基础(协议+OSI+TCPIP+网络传输的流程+IP地址+MAC地址)

【网络编程】第二章 网络套接字(socket+UDP协议程序)

【网络编程】第三章 网络套接字(TCP协议程序+多进程+多线程+线程池)


文章目录

  • 💙系列文章💙
  • 💎一、守护进程
    • 🏆1.进程组和会话
    • 🏆2.守护进程概念和特点
    • 🏆3.守护进程创建
      • setsid
      • 总结
  • 💎二、TCP英译汉
  • 💎三、TCP协议通讯流程
    • 🏆1.三次握手
      • 初始化服务器
      • 建立连接
      • 数据交互
    • 🏆2.四次挥手
      • 端口连接
  • 💎四、TCP和UDP对比


💎一、守护进程

🏆1.进程组和会话

进程组:进程组由一个进程或者多个进程组成,每个进程组有唯一的进程组ID,每个进程组有一个进程组组长(和进程组ID一样)。

会话:有一个或者多个进程组组成的集合,一个会话的几个进程组可以分为前台进程和后台进程。

🏆2.守护进程概念和特点

守护进程,精灵进程,当Linux系统启动的时候,会启动很多系统服务,这些进程服务是没有终端的也就是说你把终端关闭了这些系统服务是不会停止的,他们一直运行着他们有一个名字就叫做守护进程。

  • 生存周期长[不是必须]:一般是操作系统启动的时候他启动,操作系统关闭的时候他也关闭
  • 守护进程和终端没有关联,也就是说他们没有控制终端,所以你控制终端退出也不会导致守护进程退出
  • 守护进程是在后台运行不会占着终端,终端可以执行其它命令

🏆3.守护进程创建

setsid

#include <unistd.h>
pid_t setsid(void);

功能:创建一个新会话,谁调用这个函数,谁就成为这个新会话进程组的组长

返回值:成功返回进程ID,失败返回-1

注意:进程组组长不能调用

下面是创建一个守护进程方法,之后将下面函数加到我们之前写的TCP服务器代码中,服务器就部署到Linux代码当中,此时我们退出服务器只运行客户端也能成功运行。

#include <cstdio>
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void daemonize()
{
 int fd = 0;
 // 1. 忽略SIGPIPE
 signal(SIGPIPE, SIG_IGN);
 // 2. 让子进程成为进程组组长
 if (fork() > 0)
     exit(1);
 // 3. 设置自己是一个独立的会话
 setsid();
 // 4. 重定向0,1,2,此时fd是3,并且打开黑洞文件
 if ((fd = open("/dev/null", O_RDWR)) != -1) 
 {
     dup2(fd, STDIN_FILENO);//0
     dup2(fd, STDOUT_FILENO);//1
     dup2(fd, STDERR_FILENO);//2
     // 5. 关闭掉不需要的fd,此时完成重定向
     if(fd > STDERR_FILENO) close(fd);
 }
}

//./tcpClient _server_port _server_ip
main (int argc, char* argv[]){ 
 if(argc != 2 && argc != 3){
		cout << "Usage: " << argv[0] << " port" << " IP "<< endl;
		exit(3);
	}
	int port = atoi(argv[1]);
 string ip;
 if(argc == 3) ip = argv[2];
	daemonize();//此时我们进程是守护进程
 TcpServer svr(port, ip);
 svr.InitServer();
 svr.start();
 return 0;
}

列出所有守护进程

ps -ajx | grep server | grep -v grep

结果:下面是端口 8081 和8082的守护进程,想要关闭就直接kill -9 pid即可,(8447或者8521)

 1  8447  8447  8447 ?           -1 Ssl   1001   0:00 ./server 8081 127.0.0.1
 1  8521  8521  8521 ?           -1 Ssl   1001   0:00 ./server 8082 127.0.0.1

总结

守护进程和后台进程的区别:

守护进程和终端没有关系但是后台进程能往终端上输出东西和终端有关联

守护进程关闭终端时不受影响而,后台进程会随着终端的退出而退出

💎二、TCP英译汉

英译汉TCP服务器要做的就是,根据客户端发来的英文单词找到其对应的中文意思,然后将该中文意思作为响应数据发给客户端。

主要程序使用TCP通讯线程池代码,所以只用修改任务类中任务函数即可

英译汉时需要根据英文单词找到其对应的中文意思,因此我们需要建立一张映射表,其中英文单词作为映射表中的键值key,而中文意思作为与键值相对应的value,这里可以直接使用C++STL容器当中的unordered_map容器。

以下代码只修改了任务类中的read读取部分,将读取到的英文转化为中文然后返回给客户端

static void Service(int sock, string client_ip, int client_port)
{
char command[1024];
while (1)
{
 unordered_map<string, string> dict;
 dict.insert(std::make_pair("penguin", "企鹅"));
 dict.insert(std::make_pair("blog", "博客"));
 dict.insert(std::make_pair("socket", "套接字"));
 string value;
 ssize_t size = read(sock, command, sizeof(command) - 1); // 我们认为我们读到的都是字符串
 if (size > 0)
 {
   command[size] = '\0';
   cout << client_ip << ":" << client_port << "# " << command << endl;
   string key = command;
   auto it = dict.find(key);
   if (it != dict.end())
   {
     value = it->second;
   }
   else
   {
     value = key;
   }
   write(sock, value.c_str(), value.size());
 else if (size == 0)
 {
   // 对端关闭连接
   cout << client_ip << ":" << client_port << " close!" << endl;
   break;
 }
 else
 {
   // 读取失败
   cerr << sock << " read error!" << endl;
   break;
 }
}
// 服务结束
close(sock); // 如果一个进程对应的文件fd,打开了没有被归还,文件描述符泄漏!
cout << client_ip << ":" << client_port << " service done!" << endl;
}

结果:

//client
[Jungle@VM-20-8-centos:~/lesson38]$ ./client 8080 127.0.0.1
socket creat succes, sock: 3
connect success...
Please Enter# blog
server echo# 博客
//server
[Jungle@VM-20-8-centos:~/lesson38]$ ./server 8080 127.0.0.1
socket creat succes, sock: 3
bind success
listen success
get a new link->4 [127.0.0.1]:44420
127.0.0.1:44420# blog

💎三、TCP协议通讯流程

TCP协议的客户端/服务器程序的一般流程

在这里插入图片描述

🏆1.三次握手

初始化服务器

服务器初始化:

调用socket,创建文件描述符。
调用bind,将当前的文件描述符和IP/PORT绑定在一起,如果这个端口已经被其他进程占用了,就会bind失败。
调用listen,声明当前这个文件描述符作为一个服务器的文件描述符,为后面的accept做好准备。
调用accept,并阻塞,等待客户端连接到来。

建立连接

建立连接的过程:

调用socket,创建文件描述符。
调用connect,向服务器发起连接请求。
connect会发出SYN段并阻塞等待服务器应答(第一次)。
服务器收到客户端的SYN,会应答一个SYN-ACK段表示“同意建立连接”(第二次)。
客户端收到SYN-ACK后会从connect返回,同时应答一个ACK段"时间"(第三次)。

数据交互

数据传输的过程“:

建立连接后,TCP协议提供全双工的通信服务,所谓全双工的意思是,在同一条连接中,同一时刻,通信双方可以同时写数据,相对的概念叫做半双工,同一条连接在同一时刻,只能由一方来写数据。
服务器从accept返回后立刻调用read,读socket就像读管道一样,如果没有数据到达就阻塞等待。
这时客户端调用write发送请求给服务器,服务器收到后从read返回,对客户端的请求进行处理,在此期间客户端调用read阻塞等待服务器端应答。
服务器调用write将处理的结果发回给客户端,再次调用read阻塞等待下一条请求。
客户端收到后从read返回,发送下一条请求,如此循环下去。

🏆2.四次挥手

端口连接

服务器和客户端close的过程

断开连接的过程:

如果客户端没有更多的请求了,就调用close关闭连接,客户端会向服务器发送FIN段(第一次)。
此时服务器收到FIN后,会回应一个ACK,同时read会返回0(第二次)。
read返回之后,服务器就知道客户端关闭了连接,也调用close关闭连接,这个时候服务器会向客户端发送一个FIN(第三次)。
客户端收到FIN,再返回一个ACK给服务器(第四次)。

为什么要断开连接?

建立连接本质上是为了保证通信双方都有专属的连接,这样我们就可以加入很多的传输策略,从而保证数据传输的可靠性。但如果双方通信结束后不断开对应的连接,那么系统的资源就会越来越少。

因为服务器是会收到大量连接的,操作系统必须要对这些连接进行管理,在管理连接时我们需要“先描述再组织”。因此当一个连接建立后,在服务端就会为该连接维护对应的数据结构,并且会将这些连接的数据结构组织起来,此时操作系统对连接的管理就变成了对链表的增删查改。

如果一个连接建立后不断开,那么操作系统就需要一直为其维护对应的数据结构,而维护这个数据结构是需要花费时间和空间的,因此当双方通信结束后就应该将这个连接断开,避免系统资源的浪费,这其实就是TCP比UDP更复杂的原因之一,因为TCP需要对连接进行管理。

💎四、TCP和UDP对比

  • 可靠传输 vs 不可靠传输
  • 有连接 vs 无连接
  • 字节流 vs 数据报

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

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

相关文章

[Java]注解

文章目录⚽ 注解的概述⚽ 常见注解的使用示例&#x1f3d0; 文档相关的注解&#x1f3d0; 在编译时进行格式检查(JDK内置的三个基本注解)&#x1f3d0; 跟踪代码依赖性&#xff0c;实现替代配置文件功能⚽ 自定义注解⚽ JDK中的元注解&#x1f3d0; Retention&#x1f3d0; Tar…

【PowerDesign】制作数据流图

目录 文章目录 前言 一、下载软件 二、使用步骤 1.打开面板 2.绘制顶层0层/数据流程图 创建加工 画出数据流向 对格式进行设置 结果展示 2. 1层数据流程图 生成子加工 框图格式设置 结果展示 注意事项 3. 2层数据流程图 总结 前言 本文以图书管理系统举例&…

java开发的环保网站垃圾分类系统源码

本项目是基于springboot开发的小区垃圾分类的监管系统。为了更好的督促小区业主更好的进行垃圾分类和垃圾投放&#xff0c;本系统设计了一套积分奖罚机制&#xff0c;如果业主此次投放垃圾符合分类要求则加10积分&#xff0c;不符合则扣除200积分&#xff0c;积分不够需要进行扫…

东北大学c++实验最后一次

【问题描述】 建立两个磁盘文件f1.txt和f2.txt&#xff0c;编写程序实现以下工作&#xff1a; &#xff08;1&#xff09;从文件in.txt输入20个整数&#xff0c;分别存放在两个磁盘文件f1.txt和f2.txt中&#xff08;每个文件中放10个整数&#xff09;&#xff1b; &#xff…

【java】java集合详解

目录一.集合类型二.集合的不同三.List解析1.ArrayList2.LinkedList3.Vector四.Set解析1.HashSet2.TreeSet3.LinkedHashSet五.Map解析1.HashMap2.TreeMap3.HashTable4.ConcurrentHashMap一.集合类型 集合类型和关系(我画的比较简略&#xff0c;其中有很多继承实现关系都没有画),…

Web入门开发【三】- 准备工作

欢迎来到霍大侠的小院&#xff0c;我们来学习Web入门开发的系列课程。 首先我们来了解下这个课程能学到什么&#xff1f; 1、你将可以掌握Web网站的开发全过程。 2、了解基础的HTML&#xff0c;CSS&#xff0c;JavaScript语言。 3、开发自己的第一个网站。 4、认识很多对编…

刷爆力扣之字符串转换整数(atoi)

刷爆力扣之字符串转换整数(atoi) HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&a…

1、移动端基础

目录1、常见浏览器PC端移动端2、手机屏幕3、移动端调试方法4、视口4.1 布局视口 layout viewport4.2 视觉视口visual viewport4.3 理想视口 idea viewport **meta视口标签5、二倍图1、物理像素和物理像素比6、多倍图7 背景缩放background-size移动端背景图展示8、移动端主流方案…

IDEA创建kotlin项目

今天新建了一个kotlin项目&#xff0c;竟然不能导入jar包&#xff0c;原因是新建项目的时候&#xff0c;选择了kotlin作为Gradle的开发语音&#xff0c;kotlin语音里面&#xff0c;下面这行配置识别不了&#xff1a; implementation fileTree(dir: libs, include: [*.jar])所以…

【蓝桥杯】第10届Scratch国赛第6题程序2 -- 捉迷藏

[导读]&#xff1a;蓝桥杯大赛是工业和信息化部人才交流中心举办的全国性专业信息技术赛事。蓝桥杯大赛首席专家倪光南院士说&#xff1a;“蓝桥杯以考促学&#xff0c;塑造了领跑全国的人才培养选拨模式&#xff0c;并获得了行业的深度认可。” 春雷课堂计划推出Scratch蓝桥杯…

青龙面板搭建+QQ机器人

搭建青龙面板首先有个服务器 我这里看到华为云有活动就入手了一个 1.系统选择 centos7.9 华为云购买地址&#xff1a;https://activity.huaweicloud.com/1212_promotion/index.html 2. 服务器上安装宝塔 yum install -y wget && wget -O install.sh http://downl…

340页11万字智慧政务大数据资源平台数据治理方案

一.1.1 数据治理子系统 建设大数据治理子平台&#xff0c;提供数据标准管理、元数据管理、数据质量管理能力&#xff0c;实现对数据的规范治理与管理&#xff1b;提供数据工厂能力&#xff0c;实现对归集的数据进行清洗、加工&#xff0c;支撑业务的数据应用需求。具体&#xf…

ES6 箭头函数 Arrow Function

前言 1. ES6 前定义函数 2. ES6 箭头函数语法 3. ES6 箭头函数返回值 4. 箭头函数中的 this 到底是谁 ? 前言 ES6 新增了一种新的函数: 箭头函数 Arrow Function 箭头函数相当于匿名函数&#xff0c;简化了函数定义&#xff0c;将原函数的 function 关键字和函数名都删掉&am…

学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBlazor

大致了解了Blazor和MAUI之后&#xff0c;尝试创建一个.NET MAUI Blazor应用。 需要注意的是&#xff1a; 虽然都叫MAUI&#xff0c;但.NET MAUI与.NET MAUI Blazor 并不相同&#xff0c;MAUI还是以xaml为主&#xff0c;而MAUI Blazor则是以razor为主。 这个系列还是以MAUI Bla…

23. 【gRPC系列学习】gRPC安全认证-JWT认证

JWT 即 JSON Web Token,是用 JSON 形式安全传输信息的方法。本节介绍JWT与gRPC结合,关于JWT交互流程的介绍参考文末的链接。 1. 使用JWT客户端与服务端交互 1)客户端使用用户名、密码发送给服务端 2)服务端返回JWT数据,返回数据由三部分组成 Header:TOKEN 的类型,就是JW…

截至2022年12月共计451个信息安全国家标准 汇总

写在前面 早年刚参加信息安全工作更多的学点皮毛技术&#xff0c;到处找安全工具&#xff0c;跟踪poc&#xff0c;拿到一个就全网扫一遍&#xff0c;从来没有想过&#xff0c;系统化的安全工作应该怎样搞?我做的工作在安全体系中处于哪个阶段? 后来有机会做企业安全建设&…

二本跨专业自学编程及程序员就业之路——20W社招进银行

自学编程的道路 先做个自我介绍&#xff0c;我是一名普通二本院校的学生。在广州上学&#xff0c;21年毕业&#xff0c;非科班出身。上大学之前&#xff0c;很少接触电脑&#xff0c;连QQ都是别人送我的&#xff0c;当时还开心了好一阵子。 大学的时候&#xff0c;开始接触的第…

对美国学校制度的一点儿思考

本文作者在美国生活了几十年&#xff0c;随着对这个国家的深入了解&#xff0c;发现原来对美国的一些认知上有偏差。所以其根据在美的所见所闻&#xff0c;结合中国国内的情况&#xff0c;做了分析对照&#xff0c;在此知识人网小编仅摘录关于美国学校制度的内容以飨读者。 美国…

喜报 | 知道创宇ZoomEye Pro获评ISC 2022创新能力百强,实力入选“攻击面与资产管理领域”创新产品榜单!

12月21日&#xff0c;ISC 2022数字安全创新能力百强颁奖典礼在北京举行。 知道创宇的 ZoomEye Pro 以其先进的网络安全技术和创新产品能力&#xff0c;通过层层筛选&#xff0c;从众多产品中脱颖而出&#xff0c;入选“攻击面与资产管理领域”的创新产品榜单&#xff01;知道创…

IDEA运行缓慢,闪退解决方式——增加堆内存

目录方法一&#xff1a;通过IDE修改配置方法二&#xff1a;使用ToolBox进行设置方法三&#xff1a;直接修改vmoptions文件如果遇到速度变慢的情况&#xff0c;可能需要增加内存堆。方法一&#xff1a;通过IDE修改配置 help–>Change Memory Setting–>修改为一个合适的值…