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

TCP网络编程(一)—— 服务器端模式和客户端模式

这篇文章将会编写基本的服务器网络程序,主要讲解服务器端和客户端代码的原理,至于网络名词很具体的概念,例如什么是TCP协议,不会过多涉及。

首先介绍一下TCP网络编程的两种模式:服务器端和客户端模式:

        首先说明一下:黑色线代表状态的转换,红色线表示的是数据的传输,read 和 write 之间的循环表示:例如读取完数据,进入写入的状态,写入完再进入读取的状态,一直循环,实现了服务器和客户端之间的通信。


首先来解释一下服务器端:

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

socket() 表示创建一个套接字。套接字是网络通信的基本数据结构,用于定义通信协议(如 TCP 或 UDP)和地址族(如 IPv4 或 IPv6)。通过套接字,服务器和客户端可以在网络上传输数据,可以把套接字理解为一个编程接口,利用套接字实现程序和网络的连接,像是用户层和传输层(TCP)中间的一个抽象层,有了套接字才可以向网络发送数据。

传入的内容是(协议族,套接字类型,默认协议(通常为0))
返回:成功返回套接字描述符,失败返回-1 

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

bind() 表示将套接字绑定到一个特定的地址和端口。绑定的地址和端口标识服务器,使客户端能够找到并连接到该服务。只有套接字还不够,我还要知道是哪个主机(IP)发送的,哪个应用程序(端口)发送的,端口可以理解为电脑通信的入口和出口。

传入的内容是:(套接字描述符,地址结构体的地址,地址结构体大小)
返回:成功返回0,失败返回-1。

int listen(int sockfd, int backlog)

listen() 表示将套接字转换为监听模式,并设置等待连接的队列长度。当多个客户端请求连接时,服务器会将这些请求加入队列,按顺序处理。

传入的内容是(套接字描述符,队列的长度)
返回:成功返回0,失败返回-1。

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

accept() 表示等待接受客户端的连接请求,接收到请求,成功连接后,accept() 返回一个新的套接字,用于与该客户端通信,而原始监听套接字则继续处理新的连接请求。

传入的内容是:(套接字描述符,地址结构体的地址,地址结构体大小的地址)
返回:成功返回新的套接字描述符,失败返回-1 

ssize_t read(int sockfd, void *buf, size_t count)

read() 表示从套接字描述符中读取数据,用于接收客户端发送的消息。读取的数据存储在提供的缓冲区中。

传入的内容是:(套接字描述符,缓冲区指针(数组),要读取的字节数)
返回:成功返回实际读取的字节数,失败返回-1。

ssize_t write(int sockfd, const void *buf, size_t count)

write() 表示向套接字描述符中写入数据,用于向客户端发送响应数据。

传入的内容是:(套接字描述符,缓冲区指针(数组),要写入的字节数)
返回:成功返回实际写入的字节数,失败返回-1。

int close(int sockfd)

close()表示关闭套接字描述符。

传入的内容是:(套接字描述符)
返回:成功返回0,失败返回-1。 


接着解释一下客户端的新出现的函数:

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

connet()表示客户端向服务器发起连接请求。客户端告诉操作系统需要连接到哪个服务器的哪个端口。

传入的内容是:(套接字描述符,地址结构体的地址,地址结构体大小)
返回:成功返回0,失败返回-1。

看完这些,你会发现:套接字描述符和文件描述符很像,都可以根据描述进行写入读取和各种其他操作,其实,这就是UNIX系统和类UNIX系统(Linux系统)的抽象资源管理方式,通过整数来标识系统中的资源,使用统一的接口设计,“一切皆文件”。

看到这里,你一定有几个问题:

1.为什么客户端少了bind()和listen()的操作?

2.为什么connect操作指向了accept操作之后?

3.地址结构体的地址addr是个什么东西?

4.为什么有的函数传addr大小,有的传addr大小的地址?

1.对于服务器端来说,服务器需要绑定到固定的端口这样客户端才能知道它,对于客户端来说,操作系统会在必要的时候分配临时的本地端口和地址,不需要再绑定端口。

2.因为服务器端的accept函数是阻塞的,等待客户端发起请求,当connect发送给服务器端请求之后,才会继续进行后面的读写操作。

3.addr的类型如下:有两个成员,分别是地址族,地址和端口信息,但是这不方便我们进行设置,所以一般采用 sockaddr_in 这个结构,最后在进行强制类型转换得到sockaddr,注意这两个结构体类型大小是一样的,只是结构不一样。

struct sockaddr {sa_family_t sa_family;    // 地址族,例如 AF_INET(IPv4)或 AF_INET6(IPv6)char sa_data[14];         // 地址和端口信息
};

下面是sockaddr_in结构体类型,可以清楚地看到每个成员的含义:

struct sockaddr_in {sa_family_t sin_family;   // 地址族,通常为 AF_INET(IPv4)uint16_t sin_port;        // 端口号(16 位),以网络字节序表示struct in_addr sin_addr;  // IP 地址(32 位)char sin_zero[8];         // 保留字段,填充用
};

4.可以看到accept函数的addrlen参数是 addr 大小(变量)的地址,但是connect和bind函数的addrlen参数是 addr 大小(变量)本身,这是因为accept不知道调用者提供的 addr 缓冲区的大小可能是IPv4可能是IPv6,所以需要地址地址。

我猜测可能和TCP的三次握手或者accept返回新的套接字或者客户端分配动态端口有关系,而connect和bind函数都是用已知的套接字进行操作,所以不会进行addr大小的改变,所以可以直接传值。

这就是TCP编程的两种模式,从下篇文章开始,我们将学习如何编写服务器端和客户端的代码。

这就是文章的所有内容了,希望对你有所帮助,如有错误欢迎指出。

相关文章:

TCP网络编程(一)—— 服务器端模式和客户端模式

这篇文章将会编写基本的服务器网络程序,主要讲解服务器端和客户端代码的原理,至于网络名词很具体的概念,例如什么是TCP协议,不会过多涉及。 首先介绍一下TCP网络编程的两种模式:服务器端和客户端模式: 首先…...

03-类和对象(上)

一、类的概述 1.类的引入 类的封装:将数据和方法封装在一起,加以权限区分,用户只能通过公共方法访问私有数据。 为什么要将数据和方法封装在一起呢,而且还要通过公共方法才能访问私有数据? C语言中数据和方法分开可…...

PCL点云库入门——PCL库点云滤波算法之统计滤波(StatisticalOutlierRemoval)

1、算法原理 统计滤波算法是一种利用统计学原理对点云数据进行处理的方法。它主要通过计算点云中每个点的统计特性,如均值、方差等,来决定是否保留该点。算法首先会设定一个统计阈值,然后对点云中的每个点进行分析。如果一个点的统计特性与周…...

【机器学习】Kaggle实战信用卡反欺诈预测(场景解析、数据预处理、特征工程、模型训练、模型评估与优化)

构建信用卡反欺诈预测模型 建模思路 本项目需解决的问题 本项目通过利用信用卡的历史交易数据,进行机器学习,构建信用卡反欺诈预测模型,提前发现客户信用卡被盗刷的事件。 项目背景 数据集包含由欧洲持卡人于2013年9月使用信用卡进行交的…...

【RISC-V CPU debug 专栏 4 -- RV CSR寄存器介绍】

文章目录 Overview1. CSR寄存器访问指令2. 为何CSR地址不是4字节对齐(1) CSR寄存器空间是独立的地址空间(2) 节省编码空间(3) 对硬件实现的简化 3. CSR的物理大小和对齐无关4. RISC-V 中的 GPR 寄存器及其作用GPR 的详细用途CSR(控制状态寄存器)与 GPR 的…...

Object.defineProperty() 完整指南

Object.defineProperty() 完整指南 1. 基本概念 Object.defineProperty() 方法允许精确地添加或修改对象的属性。默认情况下,使用此方法添加的属性是不可修改的。 1.1 基本语法 Object.defineProperty(obj, prop, descriptor)参数说明: obj: 要定义…...

postgresql函数创建

postgresql的函数创建 1.创建函数的基本语法: CREATE [OR REPLACE] FUNCTION function_name(parameter_list) RETURNS return_type AS $$ BEGIN -- 函数体 END; $$ LANGUAGE language_name;2.创建函数时传入参数示例:add_user tbl_user表 | id | username | …...

ECMAScript 变量

文章目录 前言一、ECMAScript 变量二、var 关键字1、var 声明作用域2、var 声明提升(hoist)三、let 关键字四、const 关键字🔰 总结前言 任何语言的核心所描述的都是这门语言在最基本的层面上如何工作,涉及 语法、操作符、数据类型以及内置功能,在此基础之上才可以构建复…...

CAN总线波形中最后一位电平偏高或ACK电平偏高问题分析

参考:https://zhuanlan.zhihu.com/p/689336144 有时候看到CAN总线H和L的差值波形的最后一位电平会变高很多,这是什么原因呢? 实际上这是正常的现象,最后一位是ACK位。问题描述为:CAN总线ACK电平偏高。 下面分析下原因…...

【C++】22___STL常用算法

目录 一、常用遍历算法 二、常用查找算法 2.1 find 2.2 其它查找算法 三、常用排序算法 3.1 sort 3.2 其它排序算法 四、拷贝 & 替换 4.1 copy 4.2 其它算法 五、常用的算数生成算法 5.1 accumulate 5.2 fill 六、常用集合算法 6.1 set_intersection 6…...

意静明和-十成

十成 责任(健康)、使命(事业)、信念(意义)、自律(排诱)、自修(知识)、总结(四为)、执行(一事不拖)、人情&…...

easyui textbox使用placeholder无效

easyui textbox使用placeholder无效 在easyui 的textbox控件&#xff0c;请使用data-options 设定 示例 <input type text class easyui-textbox data-options "prompt:请输入您的邮箱"/>...

flux中的缓存

1. cache&#xff0c;onBackpressureBuffer。都是缓存。cache可以将hot流的数据缓存起来。onBackpressureBuffer也是缓存&#xff0c;但是当下游消费者的处理速度比上游生产者慢时&#xff0c;上游生产的数据会被暂时存储在缓冲区中&#xff0c;防止丢失。 2. Flux.range 默认…...

代码重定位详解

文章目录 一、段的概念以及重定位的引入1.1 问题的引入1.2 段的概念1.3 重定位 二、如何实现重定位2.1 程序中含有什么&#xff1f;2.2 谁来做重定位&#xff1f;2.3 怎么做重定位和清除BSS段&#xff1f;2.4 加载地址和链接地址的区别 三、散列文件使用与分析3.1 重定位的实质…...

活动预告 | Microsoft 365 在线技术公开课:让组织针对 Microsoft Copilot 做好准备

课程介绍 通过Microsoft Learn免费参加Microsoft 365在线技术公开课&#xff0c;建立您需要的技能&#xff0c;以创造新的机会并加速您对Microsoft云技术的理解。参加我们举办的“让组织针对 Microsoft Copilot for Microsoft 365 做好准备” 在线技术公开课活动&#xff0c;学…...

从0到机器视觉工程师(一):机器视觉工业相机总结

目录 相机的作用 工业相机 工业相机的优点 工业相机的种类 工业相机知名品牌 光源与打光 打光方式 亮暗场照明 亮暗场照明的应用 亮暗场照明的区别 前向光漫射照明 背光照明 背光照明的原理 背光照明的应用 同轴光照明 同轴光照明的应用 总结 相机的作用 相机…...

Docker安装(Docker Engine安装)

一、Docker Engine和Desktop区别 Docker Engine 核心组件&#xff1a;Docker Engine是Docker的核心运行时引擎&#xff0c;负责构建、运行和管理容器。它包括守护进程&#xff08;dockerd&#xff09;、API和命令行工具客户端&#xff08;docker&#xff09;。适用环境&#…...

数组的深度监听deep

场景&#xff1a;组件提供的emit事件可能被占用&#xff0c;在不能使用事件提交的情况下&#xff0c;就要上watch数组监听了&#xff0c;但是是发现只有在数组的长度发生变化的时候才会触发监听&#xff0c;这怎么行。。。。。 对于对象数组的深度监听&#xff0c;如果没有正确…...

点击锁定按钮,锁定按钮要变成解锁按钮,然后状态要从待绑定变成 已锁定(升级版)

文章目录 1、updateInviteCodeStatus2、handleLock3、InviteCodeController4、InviteCodeService5、CrudRepository 点击锁定按钮&#xff0c;锁定按钮要变成解锁按钮&#xff0c;然后状态要从待绑定变成 已锁定&#xff1a;https://blog.csdn.net/m0_65152767/article/details…...

UniApp 性能优化策略

一、引言 在当今数字化时代&#xff0c;移动应用的性能成为影响用户留存与满意度的关键因素。UniApp 作为一款热门的跨平台开发框架&#xff0c;以一套代码适配多端的特性极大提升了开发效率&#xff0c;但同时也面临着性能优化的挑战。优化 UniApp 性能&#xff0c;不仅能够让…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...