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)

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

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

相关文章

Python使用Selenium自动实现表单填写之蛇年纪念币蛇钞预约(附源码,源码有注释解析,已测试可用

Python实现纪念币预约自动填写表单 声明:本文只做技术交流,不可用代码为商业用途,文末有源码下载,已测试可用。 Part 1 配置文件改写(源码 有详细的注释说明 读取配置文件,自己组数据库,录入信息 配置文件 Part 2 主函数 每一期的xpath路径都不一样 所以需要提前去网站…

【计算机网络】期末速成(2)

部分内容来源于网络&#xff0c;侵删~ 第五章 传输层 概述 传输层提供进程和进程之间的逻辑通信&#xff0c;靠**套接字Socket(主机IP地址&#xff0c;端口号)**找到应用进程。 传输层会对收到的报文进行差错检测。 比特流(物理层)-> 数据帧(数据链路层) -> 分组 / I…

Vue3网站锚点定位

网站上实现锚点定位的方法有很多&#xff0c;今天介绍vue3实现的定位效果的方式。通过scrollIntoViewh函数的行为&#xff0c;滑动至指定的容器。 一、样式布局 <template> <div style"width: 100%; display: flex;flex-direction: column;"><div …

微信小程序实现图片拖拽调换位置效果 -- 开箱即用

在编写类似发布朋友圈功能的功能时&#xff0c;需要实现图片的拖拽排序&#xff0c;删除图片等功能。 一、效果展示 **博主的小程序首页也采用了该示例代码&#xff0c;可以在威信中搜索&#xff1a;我的百宝工具箱 二、示例代码 1.1、在自己的小程序中创建组件 1.2、组件…

五、docker的网络模式

五、docker的网络模式 5.1 Docker的四种网络模式 当你安装docker时&#xff0c;它会自动创建三个网络&#xff0c;可使用如下命令查看&#xff1a; [rootlocalhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7390284b02d6 bridge bridge lo…

ros项目dual_arm_pick-place(对比moveit配置助手生成的文件)

目录 前言正文gazebo_controllers.yaml变更ros_controllers.yaml变更simple_moveit_controllers.yaml变更moveit_planning_execution.launch变更ros_controllers.launch变更其他文件 汇总总结 前言 在本专栏前文中讲到&#xff0c;作者有moveit配置助手导出的包marmbots&#…

【uni-app 微信小程序】新版本发布提示用户进行更新

知识准备 uni.getUpdateManager文档介绍 不支持APP与H5&#xff0c;所以在使用的时候要做好平台类型的判断&#xff0c;如何判断&#xff0c;参考条件编译处理多端差异 代码参考 export const updateApp () > {const updateManager uni.getUpdateManager()updateManag…

Java-操作xls替换文本或图片

准备xls模板文件&#xff1a;template.xls 要求根据不同的产品型号和图片&#xff0c;插入到模板文件中&#xff0c;然后再填充产品信息。 准备需要替换的图片和数据 功能实现 package net.work.controller.base;import io.swagger.annotations.Api; import io.swagger.annot…

.Net学习

1 什么是.NET Core .NET是开发平台&#xff0c;.NET Framework、.NET Core、Xamaarin/Mono的统称。 .NET Framework是只能在Windows上开发的技术 .NET Core是可以跨平台开发的技术 Xamaarin/Mono是移动端开发的技术 .NET Core&#xff1a;跨平台、免费、开源&#xff0c;可…

半监督学习与数据增强

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

【成功解决:Can‘t uninstall ‘ultralytics‘. No files were found to uninstall.】

问题&#xff1a; 尝试卸载ultralytics时&#xff0c;使用pip uninstall ultralytics命令&#xff0c;已经卸载了ultralytics&#xff0c;但是仍出现Cant uninstall ultralytics. No files were found to uninstall&#xff0c;导致无法卸载干净。 原因 ultralytics相应的dis…

AcWing 3496. 特殊年份

文章目录 前言代码思路 前言 写简单题没啥。反正都是要写的&#xff0c;先把能拿到的分数拿了&#xff0c;之后有机会再去啃一啃硬骨头。啃不下来就算了。 代码 #include<bits/stdc.h> using namespace std; char a1[10],a2[10],a3[10],a4[10],a5[10]; int main(){cin…

MongoDB性能监控工具

mongostat mongostat是MongoDB自带的监控工具&#xff0c;其可以提供数据库节点或者整个集群当前的状态视图。该功能的设计非常类似于Linux系统中的vmstat命令&#xff0c;可以呈现出实时的状态变化。不同的是&#xff0c;mongostat所监视的对象是数据库进程。mongostat常用于…

【LeetCode: 999. 可以被一步捕获的棋子数 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

智创 AI 新视界 -- 优化 AI 模型训练效率的策略与技巧(16 - 1)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

专业140+总分420+上海交通大学819考研经验上交电子信息与通信工程,真题,大纲,参考书。博睿泽信息通信考研论坛,信息通信考研Jenny

考研结束&#xff0c;专业819信号系统与信号处理140&#xff0c;总分420&#xff0c;终于梦圆交大&#xff0c;高考时敢都不敢想目标&#xff0c;现在已经成为现实&#xff0c;考研后劲很大&#xff0c;这一年的复习经历&#xff0c;还是历历在目&#xff0c;整理一下&#xff…

K8S服务突然中断无法访问:报The node had condition: [DiskPressure]异常

一、背景 程序在运行过程中&#xff0c;突然无法访问&#xff0c;发现后台接口也无法访问&#xff1b;查看kuboard&#xff0c;发现报如下异常&#xff1a;The node had condition: [DiskPressure]. 继续查看磁盘使用率&#xff0c;发现系统盘使用率已经高达93%。问题前后呼应…

【工具变量】上市公司企业违规数据(企业当年是否违规、企业当年违规的次数)2000-2022年

一、测算方式&#xff1a;参考C刊《当代财经》纪亚方&#xff08;2023&#xff09;老师的研究&#xff0c;通过对上市公司被处罚涉及的年份进行追溯&#xff0c;为了保证企业违规行为变量度量的准确性&#xff0c;将追溯到公司被处罚的年份定义为违规年份。 采用两个指标对企业…

视频孪生携手视联网 智汇云舟亮相中国电信2024数字科技生态大会

12月3日&#xff0c;由中国电信主办的“2024数字科技生态大会”在广州盛大开幕。活动现场&#xff0c;前沿科技与创新理念交相辉映&#xff0c;数字科技未来蓝图徐徐展开。智汇云舟作为中国电信的战略合作伙伴&#xff0c;受邀出席本次活动。 展会期间&#xff0c;以“天翼视联…

Unity 使用LineRenderer制作模拟2d绳子

效果展示&#xff1a; 实现如下&#xff1a; 首先&#xff0c;直接上代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public class LineFourRender : MonoBehaviour {public Transform StartNode;public Transform MidNod…