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

Socket编程-tcp

1. 前言

tcp套接字编程这里,我们将完成两份代码,一份是基于tcp实现普通的对话,另一份加上业务,client输入要执行的命令,server将执行结果返回给client

2. tcp_echo_server

udp类似,前两步:创建socket文件与bindIP和port到内核,不同的是socket函数第二个参数在tcp这里我们使用SOCK_STREAM,表示提供面向字节流、可靠的传输

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

udp中,接下来我们就可以让client与server通信了,但由于tcp是面向连接的,因此需要等待client连接,在连接之前,需要将sockfd设置为监听状态

#include <sys/types.h>
#include <sys/socket.h>int listen(int sockfd, int backlog); # backlog 通常为4/8/16

服务器启动后,需要不断获取新连接

#include <sys/types.h>
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

accept返回一个文件描述符,与socket返回的文件描述符相比,两者的关系就像餐馆里的服务员与餐馆外的迎宾员,迎宾员通过各种说辞,将客人(也就是连接)引致餐馆交给服务员后转头又去迎接下一位客人,真正为客人提供服务的是餐馆里的服务员

这里的服务员就是accept返回的文件描述符,它才是真正的sockfd;迎宾员就是socket的返回值,也称为监听套接字(listensockfd)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对两者加以区分后,我们也将原来的命名加以修改,且由于后续需要用到listensocfd,将它设置为成员变量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

服务器启动,不断accept新连接,当获取一个连接失败时,进行获取下一个连接,好比迎宾员的邀请收到了你的冷落,它转头又去邀请下一位客人;当有连接到来时,交给sockfd,给连接提供服务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在提供服务时,server首先读到来自client发送的信息,需要注意的时,tcp的读写使用recv/sendudp的读写使用recvfrom/sendto

#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
# flags默认设为0

在这里,由于tcp是面向字节流的,读到的数据不一定是一个完整的报文,可能是半个,也可能是多个,需要我们进行处理,具体的细节在后面的文章中会详讲,这边就当作一个完整的数据

收到消息后,再给client回复;如果recv的返回值为0,表示client退出了,类似于管道:当读端读到0,表示写端关闭了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在client方面,创建好socket文件之后,应该要bind自身IP和port,但上一篇文章说过,不需要显示bind;server在等待连接,client则需要去连接,当连接成功时,OS会自动bind好client的IP和port

#include <sys/types.h>
#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

连接成功后,就能和server正常通信了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然,目前的代码缺点也很明显,它只能为一个client提供服务,由于client的服务是长服务,而我们只有一个进程,当第二个client来了,server在服务第一个进程,获取不上连接

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.1 多进程版本

当获取到新连接时,创建子进程,让子进程去提供服务,父进程等待;我们知道,父子进程之间独立,子进程会继承父进程的pcb,包括文件描述符表;子进程继承了父进程的listensockfdsockfd

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

父进程获取新连接拿到的sockfd,子进程会以写时拷贝的方式独有一份,此时父进程继续去获取连接,不会使用该sockfd,二我们知道文件描述符的个数是有上限的,父进程占着该文件描述符不用,可能会导致文件描述符泄漏的问题,因此,父进程要关闭sockfd

子进程只需要从父进程继承下来的sockfd即可,因此子进程最好关闭listensockfd

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

父进程在waitpid这里是阻塞等待,我们希望父进程继续去获取下一个连接,可以直接对SIGCHID进行忽略,这样子进程退出自动回收

这里使用的方法是,子进程再创建孙子进程,让后退出,父进程直接waitpid成功,继续获取下一个连接,孙子进程由于子进程先退,变成孤儿进程,被系统领养,释放的工作由系统完成

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2 多线程版本

当主线程获取到新连接时,创建新线程,让新线程去执行服务

这里的问题是:

  1. 如何调用TcpServer中的Service函数
  2. 如何将sockfdaddr传给Service函数

我们建立一个内部类,存放TcpServer的指针和需要传递的变量,使用该类创建实例传给线程函数,在线程函数中调用

同时,为了不让主线程对新线程join而阻塞,将新线程分离

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:这里不能使用上面一种方式创建实例,否则会因为释放两次ThreadData对象而导致client退出时server崩溃

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.3 线程池版本

利用之前的线程池,将Service函数作为任务交给线程池

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. command_server

我们想实现当客户端发送一条指令给服务器时,服务器执行该指令,并将执行结果返回给客户端;服务器只负责读取数据,如何处理数据交给业务板块,也就是做到IO与业务解耦

我们知道,linux下的命令是创建子进程,由子进程执行,再将执行结果返回给bash,这里也类似,当服务器收到一条指令,需要创建子进程,由子进程处理

我们有现成的接口可以直接调用

#include <stdio.h>FILE *popen(const char *command, const char *type);
# 父进程向管道读,type设为"r"

popen内部会创建管道和子进程,由子进程执行命令,再将执行结果写入管道,我们服务器就只需要向管道读取即可,返回值是一个封装的FILE*类型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们还可以限制客户端能够执行的命令

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为什么要让服务器帮我们执行命令,我们直接在linux的命令行解释器下直接执行不就行了?实际上,在云服务器中,我们的指令不是在我们本主机上执行的,都是交给一个叫sshd的服务远程执行,再将执行结果返回的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,上面的代码能帮我们更好的了解云服务器的指令执行原理

4. 支持断线重连的客户端

有时因为网络问题导致与服务器的连接断开了,每次都要我们重新启动客户端太麻烦了,我们将客户端改成能够断线后重连,当重连一定次数还是无法连接服务器,此时才退出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
[NetWork/Lesson2/2. command_server · baiyahua/Linux - 码云 - 开源中国](https://gitee.com/baiyahua/linux/tree/master/NetWork/Lesson2/2. command_server)

相关文章:

Socket编程-tcp

1. 前言 在tcp套接字编程这里&#xff0c;我们将完成两份代码&#xff0c;一份是基于tcp实现普通的对话&#xff0c;另一份加上业务&#xff0c;client输入要执行的命令&#xff0c;server将执行结果返回给client 2. tcp_echo_server 与udp类似&#xff0c;前两步&#xff1…...

Redis 之持久化

目录 介绍 RDB RDB生成方式 自动触发 手动触发 AOF&#xff08;append-only file&#xff09; Redis 4.0 混合持久化 Redis主从工作原理 总结 介绍 Redis提供了两个持久化数据的能力&#xff0c;RDB Snapshot 和 AOF&#xff08;Append Only FIle&#xff09;…...

视频监控汇聚平台:Liveweb安防监控平台实现接入监控视频集中管理方案

随着各行业数字化转型的不断推进&#xff0c;视频监控技术在行业内的安防应用及管理支撑日益增多。然而&#xff0c;由于前期规划不清晰、管理不到位等问题&#xff0c;视频监管系统普遍存在以下问题&#xff1a; 1. 各部门单位在视频平台建设中以所属领域为单位&#xff0c;导…...

ABAP - 系统集成之SAP的数据同步到OA(泛微E9)服务器数据库

需求背景 项目经理说每次OA下单都需要调用一次SAP的接口获取数据&#xff0c;导致效率太慢了&#xff0c;能否把SAP的数据保存到OA的数据库表里&#xff0c;这样OA可以直接从数据库表里获取数据效率快很多。思来想去&#xff0c;提供了两个方案。 在集群SAP节点下增加一个SQL S…...

uniapp使用ucharts修改Y、X轴标题超出换行

找到ucharts里面的u-charts.js。 Y轴的话找到drawYAxis方法。然后找到方法里面绘制文字的context.fillText方法。先把这个代码注释掉&#xff0c;然后加上下面代码 let labelLines item.split(\n); let currentY pos yAxisFontSize / 2 - 3 * opts.pix; labelLines.forEac…...

三分钟详细解读什么是Ecovadis认证?

Ecovadis认证&#xff0c;这一源自法国的全球性企业可持续性评估体系&#xff0c;宛如一面明镜&#xff0c;映照出企业在环境、社会和治理&#xff08;ESG&#xff09;领域的真实面貌。它不仅仅是一项简单的认证&#xff0c;更是一个推动全球企业和供应链向更加绿色、公正、透明…...

spring6:4、原理-手写IoC

目录 4、原理-手写IoC4.1、回顾Java反射4.2、实现Spring的IoC 4、原理-手写IoC 我们都知道&#xff0c;Spring框架的IOC是基于Java反射机制实现的&#xff0c;下面我们先回顾一下java反射。 4.1、回顾Java反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#x…...

爬取的数据能实时更新吗?

在当今数字化时代&#xff0c;实时数据更新对于企业和个人都至关重要。无论是市场分析、商品类目监控还是其他需要实时数据的应用场景&#xff0c;爬虫技术都能提供有效的解决方案。本文将探讨如何利用PHP爬虫实现数据的实时更新&#xff0c;并提供相应的代码示例。 1. 实时数…...

Linux 下使用飞鸽传书实现与Windows飞秋的通信

最近把单位的办公电脑换成Linux系统&#xff0c;但是其他同事们都使用飞秋2013进行局域网通信和文件传输&#xff0c;经过一番尝试&#xff0c;发现飞鸽传书For Linux 2014能够实现两者的互相通信。 飞鸽传书ForLINUXLinux版下载_飞鸽传书ForLINUX免费下载_飞鸽传书ForLINUX1.2…...

MongoDB分片集群搭建及扩容

分片集群搭建及扩容 整体架构 环境准备 3台Linux虚拟机&#xff0c;准备MongoDB环境&#xff0c;配置环境变量。一定要版本一致&#xff08;重点&#xff09;&#xff0c;当前使用 version4.4.9 配置域名解析 在3台虚拟机上执行以下命令&#xff0c;注意替换实际 IP 地址 e…...

qt QSettings详解

1、概述 QSettings是Qt框架中用于应用程序配置和持久化数据的一个类。它提供了一种便捷的方式来存储和读取应用程序的设置&#xff0c;如窗口大小、位置、用户偏好等。QSettings支持多种存储格式&#xff0c;包括INI文件、Windows注册表&#xff08;仅限Windows平台&#xff0…...

【Linux】ubuntu下一键配置vim

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;Linux &#x1f339;往期回顾&#x1f339;&#xff1a;Linux权限&#xff08;超详细彻底搞懂Linux的权限&#xff09; &#x1f516;流水不争&#xff0c;争的是滔滔…...

【NLP 9、实践 ① 五维随机向量交叉熵多分类】

目录 五维向量交叉熵多分类 规律&#xff1a; 实现&#xff1a; 1.设计模型 2.生成数据集 3.模型测试 4.模型训练 5.对训练的模型进行验证 调用模型 你的平静&#xff0c;是你最强的力量 —— 24.12.6 五维向量交叉熵多分类 规律&#xff1a; x是一个五维(索引)向量&#xff…...

信息系统安全防护攻防对抗式实验教学解决方案

一、引言 在网络和信息技术迅猛发展的今天&#xff0c;信息系统已成为社会各领域的关键基础设施&#xff0c;它支撑着电子政务、电子商务、科学研究、能源、交通和社会保障等多个方面。然而&#xff0c;信息系统也面临着日益严峻的网络安全威胁&#xff0c;网络攻击手段层出不…...

【笔记2-4】ESP32:freertos任务创建

主要参考b站宸芯IOT老师的视频&#xff0c;记录自己的笔记&#xff0c;老师讲的主要是linux环境&#xff0c;但配置过程实在太多问题&#xff0c;就直接用windows环境了&#xff0c;老师也有讲一些windows的操作&#xff0c;只要代码会写&#xff0c;操作都还好&#xff0c;开发…...

2024年12月6日Github流行趋势

项目名称&#xff1a;lobe-chat 项目维护者&#xff1a;arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍&#xff1a;一个开源的现代化设计的人工智能聊天框架。支持多AI供应商&#xff08;OpenAI / Claude 3 / Gemini / Ollama / Qwen / DeepSe…...

matlab读取NetCDF文件

matlab对NetCDF文件进行信息获取和读取数据 文章目录 前言一、什么是NetCDF文件二、读取NetCDF文件数据 1.引入库 2.读入数据总结 前言 在气象学中&#xff0c;许多气象数据存储在NetCDF文件中&#xff0c;后缀为.nc&#xff0c;通常可以用NCL、python和MATLAB等对该…...

RDMA驱动学习(三)- cq的创建

用户通过ibv_create_cq接口创建完成队列&#xff0c;函数原型和常见用法如下&#xff0c;本节以该用法为例看下cq的创建过程。 struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe,void *cq_context,struct ibv_comp_channel *channel,int comp_vector); cq …...

Flask使用Celery与多进程管理:优雅处理长时间任务与子进程终止技巧(multiprocessing)(subprocess)

在许多任务处理系统中&#xff0c;我们需要使用异步任务队列来处理繁重的计算或长时间运行的任务&#xff0c;如模型训练。Celery是一个广泛使用的分布式任务队列&#xff0c;而在某些任务中&#xff0c;尤其是涉及到调用独立脚本的场景中&#xff0c;我们需要混合使用multipro…...

Django模板系统

1.常用语法 Django模板中只需要记两种特殊符号&#xff1a; {{ }}和 {% %} {{ }}表示变量&#xff0c;在模板渲染的时候替换成值&#xff0c;{% %}表示逻辑相关的操作。 2.变量 {{ 变量名 }} 变量名由字母数字和下划线组成。 点&#xff08;.&#xff09;在模板语言中有…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...