【网络编程】基于TCP的服务器端/客户端

TCP是Transmission Control Protocol(传输控制协议)简写。因为TCP套接字是面向连接的,因此又称为基于流的套接字。

把协议分为多个层次,设计更容易,通过标准化操作设计开放式系统

网络层介绍

链路层

链路层是物理连接领域标准化的结果,是最基本的领域,专门定义LAN,WAN,MAN等网络标准。

IP层

选择传输数据的路径。IP是面向消息的、不可靠的协议。每次传输数据会帮选择一条路径,但并不一致,若发送路径错误则选择其他路径;若发送数据丢失或错误则无法解决。IP协议无法应对数据错误。

TCP/UDP层

TCP和UDP层以IP层提供的路径信息为基础完成实际的数据传输,故该层又称为传输层。

IP层只关注一个数据包的传输过程。传输顺序以及传输本身不可靠,添加TCP可以在交换数据过程确认对方已经收到数据,并重传丢失数据,这类通信是可靠的。

应用层

数据传输路径、数据确认过程都被隐藏到套接字内部,只需利用套接字编出程序即可。编写软件过程中,需要根据程序特点决定服务器端和客户端之间的数据传输规定,这边是应用层协议。

实现基于TCP的服务器端/客户端

调用socket函数创建套接字,声明并初始化地址信息信息结构体变量,调用bind函数向套接字分配地址如上章所示。

通过调用listen函数进入等待连接请求状态,只有调用listen函数客户端才能进入可发出连接请求的状态,即调用connect函数。

#include<sys/socket.h>
int listen(int sock,int backlog);
//成功返回0,失败返回-1

参数:sock希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字成为服务器套接字(监听套接字)。backlog连接请求等待队列。

服务器端处于等待连接请求状态是指,客户端请求连接时,受理前一直使请求处于等待状态。

客户端如果向服务器端询问:“请问我是否可以发起连接?”服务器端套接字就会亲切应答:“您好!当然可以,但系统正忙,请到等候室排号等待,准备好后会立即受理您的连接。”同时将连接请求请到等候室。调用listen函数即可生成这种门卫(服务器端套接字),listen函数的第二个参数决定了等候室的大小。等候室称为连接请求等待队列,准备好服务器端套接字和连接请求等待队列后,这种可接收连接请求的状态称为等待连接请求状态。

受理客户端连接请求

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

sock:服务器套接字的文件描述符。
addr:保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址变量参数填
充客户端地址信息。
addrlen:第二个参数addr结构体的长度,但是存有长度的变量地址。函数调用完成后,该变量即被填入客户端地址长度。

TCP客户端得默认函数调用顺序

#include<sys/socket.h>
int connect(int sock,struct sockaddr * servaddr,socklen_t addrlen);

sock---------客户端套接字文件描述符。
servaddr----保存目标服务器端地址信息的变量地址值。
eaddrlen-----以字节为单位传递已传递给第二个结构体参数servaddr的地址变量长度。

函数返回情况:1.服务器端接收连接请求    2.发生断网等异常情况而中断连接请求

注意:接受连接并不意味着服务器端调用acccpet函数,是服务器将连接请求记录到等待队列。

客户端套接字地址信息

实现服务端必给套接字分配IP地址和端口号,但客户端实现过程未出现,而是创建套接字后立即调用connect函数。网络数据交换必须分配IP和端口号,怎么?

客户端分配地址:

  • 何时:调用connect函数时
  • 何地:操作系统,内核
  • 如何:IP用计算机(主机)的IP,端口随机。

基于TCP的服务器端/客户端函数调用关系

流程:服务器端创建套接字后连续调用bind、listen函数进入等待状态,客户端通过调用connect函数发起连接请求。注意:服务器端调用listen函数才能调用connect函数。且客户端调用connect函数前,服务器端有可能率先调用accept函数。此时服务器在调用accept函数时进入阻塞状态,知道客户端调用connect函数为止。

实现迭代服务器端/客户端

服务器端将客户端传输的字符串数据原封不动地传回客户端。

实现迭代的服务器端

服务器端在同一时刻只与一个客户端相连,并提供回声服务。

服务器端依次向5个客户端提供服务并退出。

客户端接收用户输人的字符串并发送到服务器端。

服务器端将接收的字符串数据传回客户端,即“回声”服务器端与客户端之间的字符串回声一直执行到客户端输人Q为止。

存在问题:“每次调用read、write函数时都会以字符串为单位执行实际的/O操作。”
当然,每次调用write函数都会传递1个字符串,因此这种假设在某种程度上也算合理。“TCP不存在数据边界“。上述客户端是基于TCP的,因此,多次调用write函数传递的字符串有可能一次性传递到服务器端。此时客户端有可能从服务器端收到多个字符串,这不是我们希望看到的结果。还需考虑服务器端的如下情况:字符串太长,需要分2个数据包发送!在此过程中,客户端有可能在尚未收到全部数据包就调用read函数。

回声客户端传输的是字符串,且是通过调用write函数一次性发送的。之后还调用一次read函数,期待接收自己传输的字符串。问题所在。

解决方法,可以提前确定接收数据的大小。若之前传输了20字节长的字符串,则在接收时循环调用read函数读取20个字节。

若问题不在回声客服端:定义应用层协议

回声客户端可以提前知道接收的数据长度,但我们应该意识到,更多情况下这不太可能。既然如此,若无法预知接收数据长度时应如何收发数据?此时需要的就是应用层协议的定义。之前的回声服务器端/客户端中定义了如下协议。
        “收到Q就立即终止连接。”

同样,收发数据过程中也需定好规则以表示数据的边界,或提前告知收发数据的大小。服务器端/客户端实现过程中逐步定义的这些规则集合就是应用层协议。

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

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

相关文章

Win快速删除node_modules

在Windows系统上删除 node_modules 文件夹通常是一个缓慢且耗时的过程。这主要是由于几个关键因素导致的&#xff1a; 主要原因 文件数量多且嵌套深&#xff1a; node_modules 文件夹通常包含成千上万的子文件夹和文件。由于其结构复杂&#xff0c;文件和文件夹往往嵌套得非常…

JavaScript的数组排序

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

函数式开发接口( Consumer、Function)在实际开发中的应用场景

之前有个扫码下载文件需求&#xff0c;由于要同时进行记录下载人的记录。一开始用的是异步进行日志记录。发现有的用户扫码下载了一次文件&#xff0c;日志记录了三条。这种很容易联想到是因为网络抖动造成的。 问题代码 由于日志记录是异步的&#xff0c;文件下载需要时间。同…

干货下载 |《数据治理:数据中台建设与能力提升策略》

在当今这个信息爆炸的时代&#xff0c;数据已经成为企业最宝贵的资产之一。数据不仅能帮助企业洞察市场趋势&#xff0c;还能优化业务流程&#xff0c;提升运营效率&#xff0c;进而在激烈的市场竞争中占据优势地位。然而&#xff0c;如何有效地管理和利用这些数据&#xff0c;…

(代数:解一元二次方程)可以使用下面的公式求一元二次方程 ax2+bx+c0 的两个根:

(代数:解一元二次方程)可以使用下面的公式求一元二次方程 ax2bxc0 的两个根: b2-4ac 称作一元二次方程的判别式。如果它是正值,那么一元二次方程就有两个实数根。 如果它为 0&#xff0c;方程式就只有一个根。如果它是负值&#xff0c;方程式无实根。 编写程序&#xff0c;提示…

推挽与开漏输出

一般来说&#xff0c;微控制器的引脚都会有一个驱动电路&#xff0c;可以配置不同类型的数字和模拟电路接口。输出模式一般会有推挽与开漏输出。 推挽输出 推挽输出&#xff08;Push-Pull Output&#xff09;&#xff0c;故名思意能输出两种电平&#xff0c;一种是推&#xf…

DOM-获取元素

获取元素的方法&#xff1a; 方法一&#xff1a;根据id获取元素document.getElementById <div id"time">2024-6-4</div> 在script标签中&#xff1a;注意getElementById括号里面必须要有引号&#xff0c;获得的是对象类型 var timer document.getEle…

设计模式——建造者模式(生成器模式)

建造者模式(生成器模式) 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示的意图 用了建造者模式&#xff0c;那么用户就只需要指定需要构建的类型就可以得到它们&#xff0c;而具体构造的细节和过程不需要知道 概括地说&#xff0c;Bu…

2. 音视频H264

视频软件基本流程 1.什么是H264 H.264是由ITU-T视频编码专家组&#xff08;VCEG&#xff09;和ISO/IEC动态图像专家组&#xff08;MPEG&#xff09;联合组成的联合视频组&#xff08;JVT&#xff0c;Joint Video Team&#xff09;提出的高度压缩数字视频编解码器标准 H265又名高…

席卷的B站《植物大战僵尸杂交版》V2.0.88整合包,PC和手机可用,含通关存档和视频教程!

今天给大家安利一款席卷B站&#xff0c;火爆全网的游戏——《植物大战僵尸杂交版》2.0.88整合包。 这个是网络上现存植物大战僵尸杂交版的最全整合&#xff0c;包含了修改工具&#xff0c;超强通关存档和高清工具。工具包有安装视频教程&#xff0c;支持手机版和pc多端使用&am…

家用洗地机前十名排行榜:2024十大热销款式好用不踩雷

洗地机强大的清洁力和高效的清洁效率&#xff0c;迅速代替了吸尘器、电动拖把、蒸汽拖把的位置&#xff0c;成为家庭地面清洁的新宠&#xff0c;各大厂商也纷纷上新自家新品。但是这个也造成了人们在挑选机型的时候无从下手&#xff0c;甚至很多新手购机&#xff0c;几乎对洗地…

Typora 破解、激活!亲测有效!2024 最新激活方法

Typora 破解、激活&#xff01;亲测有效&#xff01;2024 最新激活方法 Typora是一款简单易用的Markdown编辑器。 Markdown是一种可以使用普通文本编辑器编写的标记语言&#xff0c;通过简单的标记语法&#xff0c;它可以使普通文本内容具有一定的格式&#xff0c;其目标是实现…

【Intel CVPR 2024】通过图像扩散模型生成高质量360度场景,只需要一个语言模型

在当前人工智能取得突破性进展的时代&#xff0c;从单一输入图像生成全景场景仍是一项关键挑战。大多数现有方法都使用基于扩散的迭代或同步多视角内绘。然而&#xff0c;由于缺乏全局场景布局先验&#xff0c;导致输出结果存在重复对象&#xff08;如卧室中的多张床&#xff0…

Armbian OS(基于ubuntu24) 源码编译mysql 5.7

最近弄了个S905X3的盒子刷完Armbian OS &#xff08;基于ubuntu24&#xff09;&#xff0c;开始折腾Arm64之旅。第一站就遇到了MySQL的问题&#xff0c;由于MySQL没有提供Arm64版本&#xff0c;又不想塞Docker镜像&#xff0c;因此选择源码来编译MySQL5.7。下面记录详细过程和遇…

Golang的GC

目录 介绍GC 概要 什么是根对象 三色标记法 什么情况下三色标记法会失效 屏障机制 “强-弱” 三色不变式 插入屏障 (强三色) 删除屏障(弱三色) Go 的混合写屏障机制 混合写屏障规则 介绍GC 概要 作用范围&#xff1a;只回收堆内存&#xff0c;不回收栈内存&#xf…

举个栗子!Tableau 技巧(276):学做径向柱状图(Radial Column Chart)

关于 径向柱状图&#xff08;Radial Column Chart&#xff09;&#xff0c;俗称环形柱状图。它的用法跟柱形图基本一致&#xff0c;不同之处在于它的值刻度是环形的&#xff0c;数值从内到外依次增加&#xff0c;柱子越长代表数值越大。 数据粉可能会问&#xff1a;径向柱形图…

独具韵味的移动端 UI 风格

独具韵味的移动端 UI 风格

10.GLM

智谱AI GLM 大模型家族 最强基座模型 GLM-130B GLM (General Language Model Pretraining with Autoregressive Blank Infilling) 基于自回归空白填充的通用语言模型&#xff08;GLM&#xff09;。GLM通过增加二维位置编码并允许以任意顺序预测跨度来改进空白填充预训练&…

SQL 截取函数

目录 1、substring 2、left 3、right 4、substring_index 1、substring 用途&#xff1a;字段截取从指定开始的字符开始&#xff0c;截取要的数&#xff1b;指定开始的字符数字可以用负的&#xff0c;指定开始的字符从后往前(向左)数&#xff0c;截取要的数不能为负。 语…

go语言 | 快速生成数据库表的 model 和 queryset

就是生成 model 目录的 xxx.go 和 xxx_gen.go 文件 使用的工具&#xff1a; 快速生成 model&#xff1a;gentool&#xff1a;https://github.com/go-gorm/gen/tree/master/tools/gentool 根据 model 生成 queryset&#xff1a;go-queryset&#xff1a;https://github.com/jirfa…