Linux套接字编程-2

news2024/12/28 2:44:33

在上一篇博客中,我们先对套接字编程的内容进行了一个简单涵盖,并详细陈述了UDP协议内容。本篇我们承接上文,讲述完UDP后,我们来讲解TCP。

目录

1.TCP协议

1.1通信两端流程

1.1.1服务端流程

1.1.2客户端流程

1.2套接字相关操作接口

1.2.1创建套接字

1.2.2绑定地址信息

1.2.3设置监听

1.2.4发送连接建立请求

1.2.5获取新建连接

1.2.6发送数据

1.2.7接收数据

1.2.8关闭套接字

1.3代码实现

1.TCP协议

TCP是传输控制协议,一种面向连接,可靠传输,提供字节流传输的服务。

1.1通信两端流程

1.1.1服务端流程

首先依旧是创建套接字,即在内核中创建一个socket结构体;然后为创建的套接字绑定地址信息;其次开始监听,对于TCP而言,它是一个存在状态的结构体,不同的状态下只能进行特定的操作,开始监听就是将TCP套接字的状态制为listen状态,只有在listen状态下时,服务端才会处理客户端的连接请求。

具体情况便是:客户端向服务端发送一个连接请求后,当服务端不处于监听listen状态时,则会丢弃该数据,不做任何处理;

当服务端处于监听状态时,则会立即为这个连接建立请求处理:为该新连接建立请求,创建一个套接字结构体,并为该新创建的套接字,描述完整的五元组信息。此后的数据通信都有这个新创建的套接字进行通信,这也就是说,一开始创建的套接字只负责新连接处理请求,不负责数据通信,并且当后续有多少客户端和服务端建立连接,便会创建多少套接字。

在监听后,是获取新连接,即从监听套接字对应的新建队列中,取出一个套接字结构体,并返回该套接字的描述符;连接建立之后,便可以开始收发数据,收发数据过程中我们所使用的套接字描述符都是从获取新连接中的得到的;最后便是关闭套接字,释放资源。

值得注意的是,TCP的数据通信当中,我们不限定必须由客户端先发送数据。因为在连接建立中,新套接字socket中已经存在了完整的五元组,也正因如此,TCP通信中,我们不需要指定对端地址。

1.1.2客户端流程

首先是创建套接字;然后是为套接字绑定地址信息(不推荐);其实是向服务端发送连接建立请求,当连接一旦建立成功,socket中就会描述一个完整的五元组信息;再是收发数据;最后关闭套接字,释放资源。

1.2套接字相关操作接口

1.2.1创建套接字

int socket(int domain, in type, int protocol);

socket是套接字创建接口,和UDP协议不同的是,我们传入TCP协议所需的参数即可实现TCP通信。

其中domain是地址域类型,ipv4 -- AF_INET;type是套接字类型,TCP选择字节流传输--流式套接字--SOCK_STREAM;protocol是协议类型--选择TCP协议--IPPROTO_TCP。

1.2.2绑定地址信息

int bind(int sockfd, struct sockaddr* addr, socklen_t addrlen);

1.2.3设置监听

int listen(int sockfd, int backlog);

listen是设置服务端为监听状态的接口,其中sockfd是创建套接字返回的监听套接字描述符;backlog是同一时刻最大并发连接数。(限制同一时刻最多有多少客户端的连接建立请求能被处理)

返回值:监听成功则返回0;失败则返回-1。

设置最大并发连接数的目的在于,避免TCP服务器对过多客户端的新连接创建socket,socket创建过多会导致服务器资源耗尽,系统崩溃。

具体做法便是:内核中每一个监听套接字都有一个新连接的socket队列,会将队列分为两类,半连接队列和已连接队列,backlog参数便是对队列的节点数量进行限制。(队列节点数量 = backlog + 1)(一旦半连接队列被放满,再又新连接到来则服务器会直接丢弃)

1.2.4发送连接建立请求

int connet(int sockfd, struct sockaddr* addr, socklen_t len);

connet是客户端向服务端发送连接建立请求接口(只有客户端会用到),其中sockfd是套接字描述符,addr是服务端地址信息,addrlen是地址长度。

1.2.5获取新建连接

int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);

accept是从内核sockfd指定的监听套接字中对应的已完成连接队列中取出一个socket接口,其中addr是accpet内部进行填充的客户端地址,是一个输出参数;addrlen是地址信息长度,是一个输入输出参数,用于指定想要获取的地址长度,以及返回实际的地址长度。

返回值:获取成功则返回新建连接的套接字描述符;失败返回-1。

1.2.6发送数据

ssize_t send(int sockfd, void* data, size_t len, int flag);

send是发送数据接口,和sendto唯一不同在于不需要指定对端地址。

返回值:发送成功则返回实际发送的数据字节长度;出错返回-1。

1.2.7接收数据

ssize_t recv(int sockfd, void* buf, size_t len, int flag);

recv是接收数据接口,和recvfrom唯一不同在于不需要获取对端地址。

返回值:接收成功则返回实际发送的数据字节长度;出错返回-1;连接断开则返回0

1.2.8关闭套接字

int close(int sockfd);

1.3代码实现

我们封装TcpSocket类,来对socket操作进行封装,简化后续使用难度,提高代码泛用性。

然后我们对封装的类进行使用,先设计出服务端代码如下:

再设计出客户端代码如下:

 最后我们进行测试:

很明显当客户端多次请求发送数据时,客户端会直接退出,并发出“connect broken”的打印字样。这是因为我们在服务端设计代码中,获取新连接之后所创建连接中的“new_sock"是一个局部变量,当循环结束时它的生命周期也随之结束。

如此便导致服务器与一个客户端通信一次之后,下次再进行通信获取到创建的客户端是新的局部变量:“new_sock"。

对于上述问题的解决,我们才可以采用多进程或多线程的方式来解决,即处理TCP服务器中多个客户端连接时创建多个socket的情况。将执行流拆分开,对于创建新的socket我们进一步创建子进程或者线程来完成对其的处理,进而实现TCP协议中的多客户端与同一个服务端的稳定通信。

具体解决思路和代码设计我们在下一篇博客中进行说明~

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

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

相关文章

LeCun、田渊栋参与撰写,70页「自监督学习」大全

来源 | 机器之心 微信号:almosthuman2014 「关于自监督学习,你想知道但又不敢问的一切都在这里了。」图灵奖得主、Meta 人工智能首席科学家 Yann LeCun 刚刚发了这样一则推文。 在推文中,LeCun 介绍了他和 Meta 人工智能研究院研究员、研究经…

数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

目录 题意理解 问题 描述 输入样例 输出样例 求解思路 建两棵二叉树 不建树 建一棵树 搜索树表示 程序框架搭建 如何建搜索树 如何判别 方法 查找函数 判断函数 其他函数 题意理解 给定一个插入序列就可以唯一确定一颗二叉搜索树。 但是,一颗给定…

libigl添加Viewer Menu时出现imgui相关的错误:无法打开包括文件: “imgui.h”: No such file or directory

libigl添加如下图所示的Viewer Menu时,出现了“无法打开包括文件: “imgui.h”: No such file or directory”的错误 很显然是libigl内嵌的imgui出了问题 从项目路径libigl-example-project-main\out\build\x64-Release\_deps\libigl-src\include\igl\opengl\glfw\…

【谷粒商城之CompletableFuture异步编排】

本笔记内容为尚硅谷谷粒商城CompletableFuture异步编排部分 目录 一、线程回顾 1 、初始化线程的 4 种方式 2.、线程池的七大参数 运行流程: 3、常见的4种线程池 4、开发中为什么使用线程池 二、CompletableFuture 异步编排 业务场景 1、创建异步对象 …

无线化超轻薄,香港城市大学体感反馈贴片WeTac

此前,青亭网曾报道香港城市大学与腾讯Robotics X Lab合作研发的低电压体感方案,原理是通过微电流刺激来模拟触觉,可模拟微小物体的体感。近期,香港城市大学的一组科研人员也公布了一项类似的方案:WeTac,该方…

轻松上手:使用VSCode调试Python模块级代码的完整教程

安装VSCode:请确保已经安装了Visual Studio Code。安装Python插件:在VSCode中,转到Extensions视图 (View -> Extensions) 并搜索"Python"。找到由Microsoft提供的插件并点击安装。重启VSCode以确保插件安装正确。准备项目&#…

边听歌边充电LDR6028+LDR9201既能充电又能OTG方案

随着type-c接口的普及,市面上的手机,平板,笔电逐渐都采用了type-c接口,设备为了不断的追求更轻薄的机身和防水要求慢慢的取消了一些影响手机外观完整性的接口,比如3.5mm耳机孔。 有线耳机用户一般会选择使用C口转3.5m…

资深架构师解读零代码开发平台—如何不写代码实现流程审批

审批节点 “审批节点:” 流程中涉及审批时,需要用到审批节点。审批可通过或者驳回,也可以发送通知。可以多人会签/或签审批。 1. 审批节点 1.1 审批设置 ① 审批方式 审批方式默认为或签方式,只一个人审批即可 当选择会签时&#…

【英语】大学英语CET考试,口语考试介绍与备考1(讲义笔记)

文章目录 1、考试基本信息2、考试题型介绍3.1 短文朗读与回答问题(语音篇)3.1.1 语音篇真题3.1.2 语音篇6项基础知识3.1.3 语音语调练习(名言名句)3.1.4 短文朗读练习材料(真题) 3.2 自我介绍与看图说话&am…

IC面试,你一定要准备好这些(内附大厂面试题目)

大家都知道,面试的表现会对于个人职业发展的重要性,不仅能决定是否录用,还会影响到后期的谈薪,所以面试前一定要做好充分的准备。 怎么准备面试? 这里就建议简历上的表述尽量客观化、专业化,多使用数字和…

目标跟踪综述 (持续更新)

这几天对目标跟踪挺感兴趣的,但是在CSDN和知乎上面找的相关介绍资料都看的一知半解,所以自己找了一篇 2022-04-26 发表的综述文章作下笔记学习下。 目录 一、基于相关滤波的目标跟踪算法 1、相关滤波视频目标跟踪算法的框架 2、相关滤波目标跟踪算法…

GPT-4开源平替miniGPT-4来了,仅需23G显存单机可run,附论文、项目代码地址

来源 | 新智元 微信号:AI-era 先是ChatGPT的发布给世界带来了一点小小的NLP震撼,随后发布的GPT-4更是破圈计算机视觉,展现了非凡的多模态能力。 不光能读懂人类的梗,给个手绘草图甚至可以直接写出网站的代码,彻底颠覆…

百度地图 TypeError: Cannot set properties of undefined (setting ‘Bm‘)

这类问题出现的原因一般是,页面还没有加载完,地图开始加载,或者地图加载在页面加载之前 在项目中,我用isMapLoading控制地图的加载,false–加载,true–不加载,在data()中设置isMapLoadingtrue

矩阵的秩的计算

definition 1 矩阵的秩 矩阵的列空间的维度 矩阵的零空间的秩 矩阵的自由变量的个数 n - r(A) definition 2 这两个证明很好证 第三个证明可以用零空间的秩 example 1 hyperlink

HTTPS建立连接原理、SSL工作原理

HTTPS与HTTP相比有什么区别? HTTPS保证安全的原理是什么? HTTPS是如何建立连接的? 巨人的肩膀 3.1 HTTP 常见面试题 | 小林coding HTTP与HTTPS的区别 HTTP是超文本传输协议,传输的内容是明文(HTTP1.1及之前版本)。HTTPS在TCP与HT…

【LeetCode】27. 移除元素

题目链接:https://leetcode.cn/problems/remove-element/ 📕题目要求: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,…

【原创】生成文件MD5图像,类似于GitHub的像素风格头像

前言 我想通过文件的md5生成关于这个md5的图像,类似于GitHub的随机像素头像,用处是让这个md5更加直观,也能用于生成各种用户头像,跟GitHub一样。 网上搜了一下,没有现成的方法,只能有一篇类似的文章可以借…

第N2周:中文文本分类-Pytorch实现

目录 一、前言二、准备工作三、数据预处理1.加载数据2.构建词典3.生成数据批次和迭代器 三、模型构建1. 搭建模型2. 初始化模型3. 定义训练与评估函数 四、训练模型1. 拆分数据集并运行模型 一、前言 🍨 本文为🔗365天深度学习训练营 中的学习记录博客 …

运算符重载----赋值运算符重载

运算符重载 本质是函数调用,内置类型编译器直接比,自定义就去找对应类内重载的函数 如果定义在类外,需要访问私有的成员函数,只能将成员函数权限变为Public或者友元(非必须不用) ,所以一般重载…

Linux程序设计之字节序转换

1.在网络通信中,数据的存储方式十分重要,因为它影响到数据的准确性。如今,电脑和网络上数据的存储方式有两种:大端模式和小端模式。大端模式:数据的高位存储在内存的低位,数据的低位存储在内存的高位。小端…