当前位置: 首页 > news >正文

Tcp协议讲解与守护进程

TCP协议:面向链接,面向字节流,可靠通信

创建tcp_server

1.创建套接字


域:依旧选择AF_INET
连接方式:  


选择SOCK_STREAM 可靠的

2.bind

3.监听装置    
  
      


client要通信,要先建立连接,client主动建立连接,所以服务端要一直等待连接


4.获取连接
  


成功返回新的sockfd,失败返回-1


  
我们在使用UDP时,我们的sockfd一直都是同一个,但是在TCP这里我们收到了一个新的sockfd,那我们客户端服务端通信的时候是用哪一个socket呢?
一个故事:有一家饭店,有一个叫张三的员工在外面拉客,拉到客后就进入餐馆叫服务员A给顾客A提供服务,所以顾客A的所有要求都由服务员A提供。
所以我们在通信时用的是返回的新的socket,我们创建的socket理论上叫Listensocket
如果失败了,返回-1,我们得让循环退出吗?
不,我们的continue让socket持续监听

提供服务
调用read write进行读写
read如果读到了0,表示读到了文件结尾,表明(对端关闭了连接)

#pragma once
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>#include <unistd.h>
#include <errno.h>#include <netinet/in.h>
#include <arpa/inet.h>#include "Log.hpp"
#include "Comm.hpp"
using namespace std;
const int defaultblacklog = 5;
class TcpServer
{
public:TcpServer(const uint16_t &port) : _port(port){}void Server(int sockfd){while (true){char buff[1024];int n = read(sockfd, buff, sizeof(buff) - 1);if (n > 0){//读取成功buff[n]=0;lg.LogMessage(Info,"read success");cout<<"#Client say:"<<buff<<endl;// string sendbuff;// cout<<"#Please Enter"<<endl;// getline(cin,sendbuff);// int m=write(sockfd,sendbuff.c_str(),sizeof(sendbuff));// if(m<0)// {//     lg.LogMessage(Fatal,"write failed errno:%d :%s",errno,strerror(errno));// }// lg.LogMessage(Info,"Write success.......");}else if(n==0){break;lg.LogMessage(Info,"Client quit.......");}else{lg.LogMessage(Fatal,"read failed errno:%d :%s",errno,strerror(errno));}}}void Init(){// 创建套接字_listensocket = socket(AF_INET, SOCK_STREAM, 0);if (_listensocket < 0){lg.LogMessage(Fatal, "create socket failed errno %d:%s\n", errno, strerror(errno));}lg.LogMessage(Debug, "create socket success _socket:%d\n", _listensocket);// bindstruct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = _port;addr.sin_addr.s_addr = INADDR_ANY;int n = bind(_listensocket, CONV(&addr), sizeof(addr));if (n < 0){lg.LogMessage(Fatal, "create socket failed errno %d:%s\n", errno, strerror(errno));}lg.LogMessage(Debug, "bind socket success _socket:%d\n", _listensocket);// 监听装置int m = listen(_listensocket, defaultblacklog);if (m < 0){lg.LogMessage(Fatal, "listen  failed errno %d:%s\n", errno, strerror(errno));}lg.LogMessage(Debug, "listen success _socket:%d\n", _listensocket);}void Start(){// 获取连接while (true){struct sockaddr_in peer;socklen_t peerlen = sizeof(peer);int wrsockfd = accept(_listensocket, CONV(&peer), &peerlen);if (wrsockfd > 0){// 获取连接成功  提供服务Server(wrsockfd);}else{// 获取连接失败 但是一直获取continue;}// 提供服务close(wrsockfd);}}~TcpServer(){}private:uint16_t _port;int _listensocket;
};

netstat -nltp 查看服务器
  


客户端


1.创建套接字 (同sever端)


2.建立连接 连接后自动进行bind


  
inet_pton:更安全
  

#include <iostream>
#include <cstring>#include <sys/types.h>
#include <sys/socket.h>#include <unistd.h>
#include <errno.h>#include <netinet/in.h>
#include <arpa/inet.h>#include "Log.hpp"
#include "Comm.hpp"
using namespace std;
void Usage(std::string proc)
{std::cout << "Usage : \n\t" << proc << "server_ip server_port\n"<< std::endl;
}
int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);cerr << "Usage error" << endl;exit(Usage_Err);}// 创建套接字int _socket = socket(AF_INET, SOCK_STREAM, 0);if (_socket < 0){lg.LogMessage(Fatal, "create socket failed errno %d:%s\n", errno, strerror(errno));}lg.LogMessage(Debug, "create socket success _socket:%d\n", _socket);// 建立连接string serverip=argv[1];uint16_t serverport=stoi(argv[2]);struct sockaddr_in serveraddr;bzero(&serveraddr,sizeof(serveraddr));serveraddr.sin_family=AF_INET;serveraddr.sin_port=serverport;if(inet_pton(AF_INET,(serverip.c_str()),&serveraddr.sin_addr));int n=connect(_socket,CONV(&serveraddr),sizeof(serveraddr));if(n<0){lg.LogMessage(Fatal, "connect failed errno %d:%s\n", errno, strerror(errno));}lg.LogMessage(Debug, "connect success _socket:%d\n", _socket);// 输入信息while(true){string buff;cout<<"Please Enter:"<<endl;getline(cin,buff);int n=write(_socket,buff.c_str(),sizeof(buff));}
}


  
main,cc

#include "TcpServer.hpp"
#include "Comm.hpp"
#include "Daemon.hpp"
void Usage(std::string proc)
{std::cout << "Usage : \n\t" << proc << "local_port\n" << std::endl;
}
int main(int argc,char* argv[])
{if(argc!=2){Usage(argv[0]);cerr<<"Usage error"<<endl;exit(Usage_Err);}uint16_t port=stoi(argv[1]);TcpServer *tcps=new TcpServer(port);tcps->Init();tcps->Start();Daemon(true,false);lg.Enable(ClassFile);
}

udp面向数据报和tcp面向字节流有什么区别?
数据报:数据和数据是有边界的    sendto一次对应着recv一次
字节流:write 一次十次一百次,read可能一次就读完,也可能几十次,但是read端与write端无关
我们编写IO代码,尤其是网络IO时,我们的read和write是有BUG的

我们的服务器得以后台进程的方式运行,真正的服务,是以后台进程以守护进程(精灵进程)的方式运行

守护进程


进程组ID 会话ID
  


同时启动的进程可以是一个进程组的,进程组id通常是其中的某一个进程的pid
  

每次我们登入linux->OS默认提供1.bash2.提供一个终端->给用户提供命令解释的服务->叫做一个会话组
在一个命令行启动的所有进程,最终都是这个会话内的一个进程组。

会话内的进程组,任何时候,一个会话内部存在很多个进程组,但是默认法人和时刻只允许一个进程组在前台(前台进程组)。

前台进程:可以接受IO的是前台进程、

jobs查看
  
fg task_number 前台
  
ctrl+Z bg task_number 后台  或者进程+&
  

守护进程自己是一个独立的会话,他不属于任何的bash会话。
谁启动setsid,谁就是会话的所属进程。
  
调用setsid的进程不能是组长,启动多个进程时,第一个启动进程就是组长,启动一个进程时,这个进程就是组长
  
所以我们一般要创建子进程,让父进程直接退出,所以守护进程一般都是孤儿进程

创建守护进程


1.忽略可能引起异常退出的信号
例如SIG_CHLD SIG_PIPE


2.让父进程退出


3.让自己成为一个新的会话setsid


4.将进程的CWD更改为/根目录     提高效率
chdir


5.独立的会话组,也就是说没有bash进程了,所以可以将所有文件dup(nullfd,1/0/2)
/dev/null 

tips:1.命名守护进程我们都以d结尾
       2.kill -9
ls /proc/pid -l

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>using namespace std;const char *rootdic = "/";
const char *nulldic = "/dev/null";
void Daemon(bool isroot, bool isclose)
{// 忽略可能引起异常的型号signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);// 守护进程不能是组长,所以得创建孤儿进程pid_t id = fork();if (id != 0)exit(0);// 创建一个新的会话setsid();// 根目录if (isroot){chdir(rootdic);}if (isclose){close(0);close(1);close(2);}else{int nullfd = open(nulldic, O_WRONLY);if (nullfd > 0){dup2(nullfd, 0);dup2(nullfd, 1);dup2(nullfd, 2);close(nullfd);}}
}

系统有没有将进程守护化的方法?
daemon
  
将服务器守护化,但企业一般都自己会实现进程守护化

相关文章:

Tcp协议讲解与守护进程

TCP协议&#xff1a;面向链接&#xff0c;面向字节流&#xff0c;可靠通信 创建tcp_server 1.创建套接字 域&#xff1a;依旧选择AF_INET 连接方式&#xff1a; 选择SOCK_STREAM 可靠的 2.bind 3.监听装置 client要通信&#xff0c;要先建立连接&#xff0…...

学习threejs,THREE.LineDashedMaterial 虚线材质,基于gosper高斯帕曲线生成雪花动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.LineDashedMaterial虚…...

LeetCode 热题100之哈希

1.两数之和 思路分析1&#xff08;暴力法&#xff09; 双重循环枚举满足num[i] nums[j] target的索引&#xff0c;刚开始不知道如何返回一对索引。后来知道可以直接通过return {i,j}返回索引&#xff1b;注意&#xff1a;j应该从i1处开始&#xff0c;避免使用两次相同的元素…...

软工——模块设计(爱啦爱啦)

过程设计的工具 一、程序流程图 程序流程图又称为程序框图&#xff0c;它是历史最悠久、使用最广泛的描述过程设计的方法。 它的主要优点是对控制流程的描绘很直观&#xff0c;便于初学者掌握。 程序流程图历史悠久&#xff0c;至今仍在广泛使用着。 程序流程图的主要缺点&a…...

Xmind一款极简思维导图和头脑风暴软件,支持PC和移动端,Xmind 2024.10.01101版本如何升级到Pro版?简单操作,最新可用!

文章目录 Xmind下载安装Xmind免费升级到Pro Xmind 是一款全功能的思维导图和头脑风暴软件&#xff0c;不限制节点和文件数&#xff0c;创新无限&#xff0c;界面纯净简洁无广告&#xff0c;支持PC和移动端&#xff0c;思维导图和大纲视图自由切换&#xff0c;可本地化文档存储&…...

自动化工具:Ansible

目录 一、运维自动化工具有哪些 二、Ansible 概述 1、Ansible 概念 2、Ansible 特点 3、Ansible 工作流程 三、安装部署Ansible 1、环境部署 2、管理节点安装 Ansible 3、查看Ansible相关文件 4、配置主机清单 5、免密管理 ssh-keygen 5.1、测试连通性 5.2、简洁输…...

我是类(最终版)

文章目录 再看构造函数类型转换static静态成员友元内部类匿名对象对象拷贝时的编译器优化 再看构造函数 本标题的目的是解决如下问题&#xff1a;当实现MyQueue时&#xff0c;我们不需要写默认构造函数&#xff0c;因为编译器会调用Stack的默认构造&#xff0c;但是&#xff0…...

详解ip route

ip route命令用于查看 Linux 系统中的路由表信息。 路由表包含的主要信息 目标网络地址&#xff08;Destination&#xff09; 显示网络的目标地址&#xff0c;可以是一个具体的网络地址&#xff08;如192.168.1.0/24&#xff09;&#xff0c;也可以是一个默认网络&#xff08;…...

OpenGL进阶系列04 - OpenGL 点精灵

一:概述 OpenGL 点精灵是一种渲染技术,用于在3D场景中渲染小的、可缩放的点。它们通常用于表示粒子效果、光源或其他小物体。点精灵会根据视图和投影矩阵自动调整大小,使其始终在屏幕上保持一致的视觉效果。实现时,点精灵通常通过使用纹理和适当的着色器来增加视觉效果。 …...

VSCode按ctrl与鼠标左键无法实现跳转的解决办法

vscode编译环境老是出问题&#xff0c;下面介绍两种解决方法 需要提前配置好代码编译需要的库以及编译器位置等等。 ctrlshiftp,输入 >C/C配置&#xff08;JSON&#xff09; 打开生成的c_cpp_properties.json {"configurations": [{"name": "Li…...

U盘数据丢失不用慌,这4个工具可以帮你恢复。

因为将大量的数据存到U盘里面很方便&#xff0c;所以U盘使用也很广泛。但是里面的数据丢失想必很多朋友都碰到过&#xff0c;不过现在有很多方法都可以帮助大家将数据回顾回来。这里我便筛选了几款比较好的数据恢复工具&#xff0c;在这里跟大家分享。 1、福昕U盘恢复软件 直通…...

如何在Ubuntu上挂载一块硬盘:详解方案与实操步骤【小白无坑版】

如何在Ubuntu上挂载一块硬盘&#xff1a;详解方案与实操步骤 一、引言 在日常的开发或使用中&#xff0c;我们经常会遇到这样的场景&#xff1a;系统硬盘空间不足&#xff0c;需要额外挂载一块硬盘以扩展存储&#xff1b;或者我们需要将一块新硬盘用于专门存储数据或备份项目…...

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…...

go-zero系列-限流(并发控制)及hey压测

参考地址&#xff1a; go-zero系列-限流(并发控制)&#xff1a;https://go-zero.dev/docs/tutorials/service/governance/limiter hey地址&#xff1a;https://github.com/rakyll/hey1、压测工具hey下载安装&#xff1a; 会安装到GOPATH/bin目录下 go install github.com/ra…...

Electron-(三)网页报错处理与请求监听

在前端开发中&#xff0c;Electron 是一个强大的框架&#xff0c;它允许我们使用 Web 技术构建跨平台的桌面应用程序。在开发过程中&#xff0c;及时处理网页报错和监听请求是非常重要的环节。本文将详细介绍 Electron 中网页报错的日志记录、webContents 的监听事件以及如何监…...

银河麒麟(debian)下安装postgresql、postgis

1、安装postgresql、postgis sudo apt update sudo apt install postgresql postgresql-contrib sudo apt install postgis postgresql-12-postgis-32、创建一个使用postgis的数据库 sudo -i -u postgres #postgres管理员用户createdb gisdb #创建新的gisdb数据库 psql -d gi…...

【已解决】【Hadoop】 Shell命令易错点及解决方法

Hadoop是一个强大的分布式系统&#xff0c;用于处理大规模数据集。在使用Hadoop的过程中&#xff0c;熟练掌握其Shell命令是必不可少的。本文将介绍几个常用的Hadoop Shell命令&#xff0c;并总结一些常见的操作错误及其解决方法。 Hadoop Shell命令简介 Hadoop提供了多种She…...

ST7789读取ID错误新思路(以STC32G为例)

1.前言 前两天刚把ST7789写入搞定&#xff0c;这两天想折腾一下读取。最开始是读ID&#xff0c;先是用厂家送的程序&#xff0c;程序里面用的是模拟I8080协议&#xff0c;一切正常。后来我用STC32G的内置LCM模块&#xff0c;发现读取不出来。更神奇的是ID读不出来&#xff0c;…...

【MySQL】入门篇—基本数据类型:使用ORDER BY进行排序

MySQL作为一种流行的关系数据库管理系统&#xff0c;提供了强大的数据查询功能&#xff0c;其中ORDER BY子句用于对查询结果进行排序。排序可以帮助用户更直观地查看数据&#xff0c;发现趋势或异常&#xff0c;尤其在处理大量数据时尤为重要。 应用场景&#xff1a; 用户管理…...

java线程池bug的一些思考

科学需要对前人的怀疑&#xff0c;对权威的怀疑。 但是上学的时候&#xff0c;我们也需要去理解课本。 现在网上充斥了“java 线程池的缺点”这一观点。分析了一下线程池的工作原理&#xff0c;确实也存在这些问题。 Java线程池工作原理。核心线程数&#xff0c;最大线程数&…...

Stitches项目架构分析:RequireJS模块化设计与Grunt构建流程完全指南 [特殊字符]

Stitches项目架构分析&#xff1a;RequireJS模块化设计与Grunt构建流程完全指南 &#x1f680; 【免费下载链接】stitches HTML5 Sprite Sheet Generator 项目地址: https://gitcode.com/gh_mirrors/sti/stitches Stitches是一个基于HTML5的雪碧图生成器&#xff0c;它采…...

Redis分布式锁进阶第二十篇

一、本篇前置衔接 第二十篇我们完成了全系列终局复盘&#xff0c;整理了故障排查SOP与企业级落地铁律。常规单资源锁、热点分片锁、隔离锁全部讲透&#xff0c;但真实复杂业务永远不是单一资源&#xff1a;下单要扣库存、扣优惠券、扣积分、冻结余额&#xff0c;多资源并行争抢…...

Simulink中Repeating Sequence锯齿波显示恒为0解决方案

锯齿波设置如图1时&#xff0c;其示波器显示恒为0&#xff08;如图2&#xff09;。图1图2于是新建模型&#xff0c;只添加Repeating Sequence模块&#xff0c;采用原始设置发现可以正常输出锯齿波&#xff0c;于是调整时间参数&#xff0c;发现当时间设置为≥[0 0.06]时可以正常…...

解决Claude Code访问不稳定与Token不足的痛点

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 解决Claude Code访问不稳定与Token不足的痛点 许多开发者将Claude Code作为日常编程的得力助手&#xff0c;用于代码生成、问题调试…...

告别CAJ格式困扰:3分钟学会用开源工具将知网文献转为PDF

告别CAJ格式困扰&#xff1a;3分钟学会用开源工具将知网文献转为PDF 【免费下载链接】caj2pdf Convert CAJ (China Academic Journals) files to PDF. 转换中国知网 CAJ 格式文献为 PDF。佛系转换&#xff0c;成功与否&#xff0c;皆是玄学。 项目地址: https://gitcode.com/…...

别急着扔!12年老ThinkPad X230升级SSD和内存后,Win10流畅得像新电脑

12年老ThinkPad X230重生指南&#xff1a;极简升级打造流畅办公利器每次打开抽屉看到那台积灰的ThinkPad X230&#xff0c;总有种说不出的情感。这款2012年问世的经典商务本&#xff0c;曾陪伴无数人度过加班到凌晨的夜晚。如今性能确实有些力不从心&#xff0c;但直接丢弃又觉…...

Spring Security OAuth2 /oauth/token 401原因与Content-Type规范

1. 问题现场还原&#xff1a;一个看似简单却让开发停摆两小时的/oauth/token请求刚接手一个老项目做安全加固&#xff0c;第一件事就是验证OAuth2密码模式的token获取流程。我照着文档写了一条curl命令&#xff1a;curl -X POST http://localhost:8080/oauth/token回车执行&…...

3个步骤彻底解决WSA安装失败问题:从错误代码到完美运行

3个步骤彻底解决WSA安装失败问题&#xff1a;从错误代码到完美运行 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or KernelSU (root so…...

DeepSeek安全测试辅助Prompt工程白皮书(含17个CVE靶场验证指令模板)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek安全测试辅助 DeepSeek系列大模型在代码生成、漏洞模式识别与安全上下文理解方面展现出独特优势&#xff0c;可作为安全测试工程师的智能协作者。其对OWASP Top 10、CWE分类体系及常见PoC结构具…...

Unity中MMD初音资源导入与动画落地全流程指南

1. 这不是普通模型包&#xff1a;初音跳舞资源在Unity中的真实价值定位“Unity初音跳舞精品模型动画资源分享”——看到这个标题&#xff0c;很多刚接触Unity的美术向开发者第一反应是&#xff1a;“哇&#xff0c;能直接放进项目里做Demo了&#xff01;”但我在带三个独立游戏…...