Liunx 套接字编程(2)TCP接口通信程序
1.TCP通信程序的编写
面向连接、可靠传输、提供字节流传输服务
客户端向服务器发送一个连接建立的请求流程,上图中服务端第三步详细流程
2.TCP接口
socket--创建套接字
int socket(int domain, int type, int protocol);
bind---绑定
intbind(int sockfd, struct sockaddr*addr, socklen_len); sockfd : socket返回的套接字描述符
addr: 要绑定的地址信息(不同地址域类型,有不同的地址结构)
listen--监听
int listen(int sockfd, int backlog);
注意:listen第二个参数限制的是,同一时刻最大并发连接数,而不是总体能建立的连接数量,因为随着accept取出一个已完成连接,就又可以建立一个新的连接放在队列中。
connect--向服务端发送连接请求,这个接口只有客户端用到
int connect(int sockfd, struct sockaddr *adddr, socklen_t len); sockfd:套接字描述符
addr: 服务端的地址信息
addrlen:地址长度
accept--获取新建连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 从内核sockfd指定的监听套接字对应的已完成连接队列中,取出一个socket,并返回这个socket的描述符
通过addr参数返回具体连接请求来源于哪个客户端
addr: accept内部进行填充客户端地址,是一个输出参数
addrlen: 地址信息长度,输入输出参数,用于指定想要获取的地址长度,以及返回实际的地址长度
返回值: 成功则返回新建连接的套接字描述符; 出错返回-1
send/recv--收发数据
ssize_t send(int sockfd, void *data, size_t len, int flag); 相较于sendto不用在指定对端地址了返回值: 成功则返回实际发送的数据长度; 出错则返回-1
ssize_t recv(int sockfd, void *buf, size_t len, int flag); 相较于recvfrom,不用获取对端地址了返回值: 成功则返回实际发送的字节长度; 出错则返回-1; 连接断开则返回0
tcp是面向连接的,一旦连接断开 (对方可能关闭了连接,或者网络出问题了......)将无法继续通信
recv函数返回0,没有读到数据是一回事,最主要的是要告诉使用者连接断开了
close--关闭套接字
int close(int fd); 3.封装一个TCPSocket类
主要是对socket操作进行封装,简化使用难度,下面为主要过程,具体代码见xshell
问题的探讨:
tcp服务器,涉及到对多个socket进行操作 (有多少客户端连接上来,就有多少socket)每一个socket都需要 accept, recv, send,但是这三个操作都是阻塞操作,
accept,如果没有新连接到来就会阻塞
recv,如果客户端没有发送数据就会阻塞
因此一旦获取了一个新连接,但是这个新连接,一直不发送数据,就会卡在recv处,没办法去调用accept获取下一个连接了而一旦一个连接通信完毕,程序流程运行到accept,但是这时没有新连接,就会卡在这里,就算上一个连接发送数据,也无法处理
tcp服务器觉得别扭的本质原因: 在一个执行流中进行的操作太多,并且这些操作都是阻塞操作。
解决方案:既然一个执行流中不能进行多个阻塞操作,干脆就创建多个执行流(多执行流任务处理)
主执行流只干一件事: 针对监听套接字获取新建连接,获取了一个新连接,就为这个新连接的操作创建一个执行流
其他执行流干的事情: 每个执行流都只负责与一个客户端通信
这样做有个好处,任意一个线程阻塞,都不会影响其他线程,也就是不会影响与其他客户端的通信
具体的实现过程分为两种: 多进程,多线程
多进程: 稳定,健壮
多线程:灵活,消耗小。
多进程方案实现
多进程方案实现: accept之后,创建子进程;但是需要注意僵尸进程的处理
相较于多进程版本,流程上没有大的差别,也是获取一个新建连接之后,创建一个线程出来
注意事项:
线程间是共用同一个文件描述符表,因此对这个通信套接字描述符的操作,只能由负责这个描述符操作的线程进行关闭,其他的线程不能关闭。
局部变量的使用,线程创建的时候,千万要注意传参,不能因为传递局部变量地址,而导致线程内访问的时候出现内存访问错误
4.tcp通信程序编写与运行中遇到的一些特殊情况
连接断开: tcp是面向连接的通信,一旦连接断开就无法通信
问题:如何在代码中知道连接断开了? 连接断开后,在代码中的体现是什么?
当recv函数接收数据的时候,返回0,代表的不仅仅是没有接收到数据,更多是为了表示连接断开了!!!
当send函数发送数据的时候,程序直接异常 (SIGPIPE) 退出,
因此如果网络通信中,不想让程序因为连接断开而导致发送数据的时候程序异常退出,就对SIGPIPE信号进行处理
问题: 有时候网络程序关闭后,无法立即启动,会bind绑定地址报错,绑定失败,地址已经被使用
网络通信程序,如果程序是主动关闭的一方,程序会无法立即启动
因为一个程序主动关闭了连接,这个连接并不会立即被释放(对应的地址和端口依然被占用),而是要等待一段时间。
netstat-anptu命令
这是查看主机上所有网络连接状态的命令
相关文章:
Liunx 套接字编程(2)TCP接口通信程序
1.TCP通信程序的编写 面向连接、可靠传输、提供字节流传输服务 客户端向服务器发送一个连接建立的请求流程,上图中服务端第三步详细流程 2.TCP接口 socket--创建套接字 int socket(int domain, int type, int protocol); bind---绑定 intbind(int sockfd, struct s…...
8年开发经验,浅谈 API 管理
随着信息化飞速增长的还有各信息系统中的应用接口(API),API作为信息系统内部及不同信息系统之间进行数据传输的渠道,其数量随着软件系统的不断庞大而呈指数型增长,如何管理这些API已经在业界变得越来越重要,…...
【软考备战·四月模考】希赛网四月模考软件设计师上午题
文章目录 一、成绩报告二、错题总结第一题第二题第三题第四题第五题第六题第七题第八题第九题第十题第十一题第十二题第十三题第十四题第十五题第十六题第十七题第十八题第十九题第二十题第二十一题第二十二题 三、知识查缺 题目及解析来源:2023上半年软考-模考大赛…...
MySQL中的@i:=@i+1用法详解
在MySQL中,i:i1是一个非常有用的表达式,用于在查询中生成一个递增的序列号。它可以帮助我们对结果进行编号,或者在需要连续的数字序列时提供便利。 我们先来了解一下MySQL中的用户变量。用户变量是一个用户定义的变量,其以开头。…...
web安全第一天 ,域名,dns
第一天 什么是域名?域名就是网络地址 在hhtp之后的就是域名 域名在哪里注册呢 国内注册商有很多,在网络上搜索一下阿里云万网就可以注册 什么是二级域名和多级域名 域名通常都是www.开头 ,而www.被称为顶级域名,在搜索的时候…...
【Linux】Linux编辑神器vim的使用
目录 一、Vim的基本概念 二、Vim的基本操作 1、进入vim 2、正常模式切换至插入模式 3、插入模式切换至正常模式 4、正常模式切换至底行模式 5、退出Vim编辑器 三、Vim正常模式命令集 1、移动光标 2、删除文字 3、复制 4、替换 5、撤销 四、Vim底行模式命令集 1、列出行号 2、光…...
vulnhub渗透测试靶场练习1
靶场介绍 靶场名:Medium_socialnetwork 下载地址:https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 环境搭建 靶机建议选择VM VirtualBox,我一开始尝试使用VMware时会报错,所以改用VM VirtualBox,攻击机使用…...
Uart,RS232,RS485串口通讯协议学习
目录 定义 UART(通常被称为串口,简单意味着使用广泛,具有普适性) RS232 RS232电平转换 RS485 -Recommended Standard (再推荐标准) 485和232的对比 RS485组网 总结 定义 串口是我们都很熟悉的,尤其是需要串口调试的时候,打印信息插…...
UML中的assembly关系
UML中的assembly关系 1.什么是Assembly关系 在UML(统一建模语言)中,"assembly"(组装)是一种表示组件之间关系的关联关系。组件是系统中可替换和独立的模块,可以通过组装来构建更大的系统。 当一…...
[Python]缓存cachetools与TTLCache简介
文章目录 cachetools缓存策略缓存操作 TTLCache cachetools是一个Python第三方库,提供了多种缓存算法的实现。 cachetools 使用前需要先安装pip install cachetools,说明文档参见https://cachetools.readthedocs.io/en/latest/。 cachetools提供了五种…...
现在的00后,真是卷死了呀,辞职信已经写好了·····
都说00后躺平了,但是有一说一,该卷的还是卷。这不,三月份春招我们公司来了个00后,工作没两年,跳槽到我们公司起薪23K,都快接近我了。 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了…...
【wpf】列表类,用相对源时,如何绑定到子项
前言 在之前的一篇文章 :《【wpf】深度解析,Binding是如何寻找数据源的》https://blog.csdn.net/songhuangong123/article/details/126195727#:~:text%E3%80%90wpf%E3%80%91%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90%EF%BC%8CBinding%E6%98%AF%E5%A6%82%E4…...
头歌计算机组成原理实验—运算器设计(3)第3关:4位快速加法器设计
第3关:4位快速加法器设计 实验目的 帮助学生掌握快速加法器中先行进位的原理,能利用相关知识设计4位先行进位电路,并利用设计的4位先行进位电路构造4位快速加法器,能分析对应电路的时间延迟。 视频讲解 实验内容 利用前一步设…...
Java中synchronized的优化
本文介绍为了实现高效并发,虚拟机对 synchronized 做的一系列的锁优化措施 高效并发是从 JDK5 升级到 JDK6 后一项重要的改进项,HotSpot 虚拟机开发团队在 JDK6 这个版本上花费了大量的资源去实现各种锁优化技术,如适应性自旋(Ada…...
软件测试技术课程:软件测试流程
软件测试流程如下: 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写,用于确定各个测试阶段的目标和策略。这个过程将输出测试计划,明确要完成的测试活动&#x…...
【Redis】聊一下缓存双写一致性
缓存虽然可以提高查询数据的的性能,但是在缓存和数据 进行更新的时候 其实会出现数据不一致现象,而这个不一致其实可能会给业务来带一定影响。无论是Redis 分布式缓存还是其他的缓存机制都面临这样的问题。 数据不一致是如何发生? 数据一致…...
Java学习笔记-04
目录 静态成员 mian方法 多态 抽象类 接口 内部类 成员内部类 静态内部类 方法内部类 匿名内部类 静态成员 static关键字可以修饰成员方法,成员变量被static修饰的成员,成员变量就变成了静态变量,成员方法就变成了静态方法static修…...
pubspec.yaml 第三方依赖版本控制
以下是一些常见的版本控制方式: 精确版本号:您可以指定特定的版本号,例如 dependency_name: 1.2.3。这将确保只有指定的版本被安装和使用。 范围约束:您可以使用比较运算符来指定版本范围,例如 dependency_name: ^1.2…...
打印机出现错误0x00000709的原因及解决方法
一般来说,出现错误0x00000709,可能是用户试图设置默认打印机时,系统无法完成操作的错误。这种错误通常发生在Windows 10或Windows 7操作系统上。**驱动人生**分析,其原因可能是以下几种情况: 1、已经设置了另一个打印…...
代码随想录算法训练营第二十九天|491.递增子序列、46.全排列、47.全排列 II
目录 491.递增子序列 46.全排列 47.全排列 II 491.递增子序列 本题和大家刚做过的 90.子集II 非常像,但又很不一样,很容易掉坑里。 代码随想录 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
npm安装electron下载太慢,导致报错
npm安装electron下载太慢,导致报错 背景 想学习electron框架做个桌面应用,卡在了安装依赖(无语了)。。。一开始以为node版本或者npm版本太低问题,调整版本后还是报错。偶尔执行install命令后,可以开始下载…...
Unity-ECS详解
今天我们来了解Unity最先进的技术——ECS架构(EntityComponentSystem)。 Unity官方下有源码,我们下载源码后来学习。 ECS 与OOP(Object-Oriented Programming)对应,ECS是一种完全不同的编程范式与数据架构…...
