《TCP IP网络编程》第四章

news2024/11/27 4:03:27

第 4 章 基于 TCP 的服务端/客户端(1)

        根据数据传输方式的不同,基于网络协议的套接字一般分为 TCP 套接字和 UDP 套接字。因为 TCP 套接字是面向连接的,因此又被称为基于流(stream)的套接字。        

        TCP 是 Transmission Control Protocol (传输控制协议)的简写,意为「对数据传输过程的控制」。

        下图为TCP/IP 协议栈:

        TCP/IP 协议栈共分为 4 层,可以理解为数据收发分成了 4 个层次化过程,通过层次化的方式来解决问题。 下面分别介绍一下4个层:

  • 链路层

            链路层是物理链接领域标准化的结果,也是最基本的领域,专门定义LAN、WAN、MAN等网络标准。若两台主机通过网络进行数据交换,则需要物理连接,链路层就负责这些标准。

  • IP 层

            准备好物理连接后就要传输数据。为了在复杂网络中传输数据,首先要考虑路径的选择。向目标传输数据需要经过哪条路径?解决此问题的就是IP层,该层使用的协议就是IP。

             IP 是面向消息的、不可靠的协议。每次传输数据时会帮我们选择路径,但并不一致。如果传输过程中发生错误,则选择其他路径,但是如果发生数据丢失或错误,则无法解决。换言之,IP协议无法应对数据错误。

  • TCP/UDP 层

            IP 层解决数据传输中的路径选择问题,只需照此路径传输数据即可。TCP 和 UDP 层以 IP 层提供的路径信息为基础完成实际的数据传输,故该层又称为传输层。                                        TCP 可以保证数据的可靠传输,但是它发送数据时以 IP 层为基础(这也是协议栈层次化的原因)。IP 层只关注一个数据包(数据传输基本单位)的传输过程。因此,即使传输多个数据包,每个数据包也是由 IP 层实际传输的,也就是说传输顺序及传输本身是不可靠的。若只利用IP层传输数据,则可能导致后传输的数据包B比先传输的数据包A提早到达。另外,传输的数据包A、B、C中可能只收到A和C,甚至收到的C可能已经损毁 。                                           反之,若添加 TCP 协议则按照如下对话方式进行数据交换:                                            

    这就是 TCP 的作用。如果交换数据的过程中可以确认对方已经收到数据,并重传丢失的数据,那么即便IP层不保证数据传输,这类通信也是可靠的。

  • 应用层

            上述内容是套接字通信过程中自动处理的。选择数据传输路径、数据确认过程都被隐藏到套接字内部。向程序员提供的工具就是套接字,只需要利用套接字编出程序即可。编写软件的过程中,需要根据程序的特点来决定服务器和客户端之间的数据传输规则,这便是应用层协议。

     

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

        下图为TCP 服务端的默认函数的调用程序 :

  • 调用 socket 函数创建套接字,声明并初始化地址信息的结构体变量,调用 bind 函数向套接字分配地址。
  • 进入等待连接请求状态:

    已经调用了 bind 函数给套接字分配地址,接下来就是要通过调用 listen 函数进入等待链接请求状态。只有调用了 listen 函数,客户端才能进入可发出连接请求的状态。客户端可以调用 connect 函数,向服务端请求连接,对于客户端发来的请求,先进入连接请求等待队列,等待服务端受理请求。

#include <sys/socket.h>
int listen(int sockfd, int backlog);
//成功时返回0,失败时返回-1
//sock: 希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数称为服务端套接字
//backlog: 连接请求等待队列的长度,若为5,则队列长度为5,表示最多使5个连接请求进入队列            
  • 受理客户端连接请求:

    调用 listen 函数后,套接字应该按序受理客户端发起的连接请求。受理请求就是服务端处理一个连接请求,进入可接受客户端数据的状态。进入这种状态所需的部件是套接字,但是此时使用的不是服务端套接字,此时需要另一个套接字,但是没必要亲自创建,下面的函数将自动创建套接字。

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*
成功时返回文件描述符,失败时返回-1
sock: 服务端套接字的文件描述符
addr: 受理的请求中,客户端地址信息会保存到该指针指向的地址
addrlen: 该指针指向的地址中保存第二个参数的结构体长度
*/

        

        accept 函数受理连接请求队列中待处理的客户端连接请求。函数调用成功后,accept 内部将产生用于数据 I/O 的套接字,并返回其文件描述符。需要强调的是套接字是自动创建的,并自动与发起连接请求的客户端建立连接。

注意:accept 函数返回的套接字不等于服务端套接字,也需要通过 close 函数关闭。

        下图为TCP 客户端的默认函数调用顺序:

        与服务端相比,区别就在于「请求连接」,它是创建客户端套接字后向服务端发起的连接请求。服务端调用 listen 函数后创建连接请求等待队列,之后客户端即可请求连接。

#include <sys/socket.h>
int connect(int sock, struct sockaddr *servaddr, socklen_t addrlen);
/*
成功时返回0,失败返回-1
sock:客户端套接字文件描述符
servaddr: 保存目标服务器端地址信息的变量地址值
addrlen: 第二个结构体参数 servaddr 变量的字节长度
*/

 

客户端调用 connect 函数后,发生以下函数之一才会返回(完成函数调用):

  • 服务端接受连接请求
  • 发生断网等异常状况而中断连接请求

        注意:接受连接不代表服务端调用 accept 函数,其实只是服务器端把连接请求信息记录到等待队列。因此 connect 函数返回后并不应该立即进行数据交换。

        客户端在调用connect函数时自动分配主机的IP,随机分配端口。无需调用标记的bind函数进行分配。

        

        下图为基于 TCP 的服务端/客户端函数调用关系:

  • 客户端只能等到服务端调用 listen 函数后才才能调用 connect 函数
  • 服务器端可能会在客户端调用 connect 之前调用 accept 函数,这时服务器端进入阻塞(blocking)状态,直到客户端调用 connect 函数后接收到连接请求。

实验:实现迭代服务端/客户端:

        程序运行的基本方式:

  • 服务器端在同一时刻只与一个客户端相连,并提供回声服务。
  • 服务器端依次向 5 个客户端提供服务并退出。
  • 客户端接受用户输入的字符串并发送到服务器端。
  • 服务器端将接受的字符串数据传回客户端,即「回声」
  • 服务器端与客户端之间的字符串回声一直执行到客户端输入 Q 为止。

服务器端:

5个客户端:

(客户端没显示完全)

        在一个服务端开启后,用另一个终端窗口开启客户端,然后程序会让你输入字符串,然后客户端输入什么字符串,客户端就会返回什么字符串,按 q 退出。这时服务端的运行并没有结束,服务端一共要处理 5 个客户端的连接,所以另外开多个终端窗口同时开启客户端,服务器按照顺序进行处理。

回声客户端存在的问题:

        以上客户端代码有一个假设「每次调用 read、write函数时都会以字符串为单位执行实际 I/O 操作」

        但是「第二章」中说过「TCP 不存在数据边界」,上述客户端是基于 TCP 的,因此多次调用 write 函数传递的字符串有可能一次性传递到服务端。此时客户端有可能从服务端收到多个字符串,这不是我们想要的结果。还需要考虑服务器的如下情况:

「字符串太长,需要分 2 个包发送!」

        服务端希望通过调用 1 次 write 函数传输数据,但是如果数据太大,操作系统就有可能把数据分成多个数据包发送到客户端。另外,在此过程中,客户端可能在尚未收到全部数据包时就调用 read 函数。

        以上的问题都是源自 TCP 的传输特性,解决方法在第 5 章。


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

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

相关文章

烧屏现象对OLED屏幕质量的影响:如何保持画面清晰度?

OLED&#xff08;Organic Light Emitting Diode&#xff09;屏幕作为一种高品质、高对比度和鲜艳色彩的显示技术&#xff0c;越来越受到消费者的青睐。然而&#xff0c;一些用户可能会担心OLED屏幕烧屏的问题。本文将探讨OLED屏幕烧屏的原因、如何预防烧屏以及如何进行正确的维…

一个完整的项目是怎么做性能测试?资深8年测试总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 突然有一天&#…

解决问题:解除HUE下载10万行的限制

解决问题&#xff1a;解除HUE下载10万行的限制 这个目录下的 vim /opt/cloudera/parcels/CDH/lib/hue/apps/beeswax/src/beeswax/conf.py可以调整数量 也可以更改为-1&#xff08;表示不限制&#xff09;

有测试媛的IT团队,产品质量更高

我们都知道&#xff0c;在绝大部分技术团队中&#xff0c;往往阳盛阴衰。而测试团队&#xff0c;可能情况要好一些&#xff0c;据部分机构调查来看男女比例在3:2左右。 根据过往经验来看&#xff0c;有测试媛的IT团队&#xff0c;往往软件质量能更好的得到保证&#xff08;强调…

【单片机】MSP430F5529单片机的Flash读写控制,MSP430 flash 读写

文章目录 内存模型程序 内存模型 https://qq742971636.blog.csdn.net/article/details/108892807 单片机的Flash里面的区域不是全都能写的&#xff1a;https://blog.csdn.net/u014470361/article/details/79297601 找一下手册看看MSP430F5529单片机哪些地址区域能写&#xf…

nginx常用命令以及安装

目录 前言&#xff1a; 安装&#xff1a; 常用命令&#xff1a; 前言&#xff1a; Nginx的设计理念是高性能、稳定性、开放性和易用性。它的并发能力优秀&#xff0c;可以处理数万个并发连接&#xff0c;并且占用较少的资源。此外&#xff0c;Nginx支持热部署&#xff0c;即…

如何将企业联系方式API接口应用于你的移动端APP?

在现代商业世界中&#xff0c;企业需要提供一种快速&#xff0c;高效的方式来让用户获取联系方式。因此&#xff0c;企业联系方式API接口应运而生&#xff0c;它是一种提供了企业联系方式的开放接口&#xff0c;在用户调用时&#xff0c;可以实现即时获取企业的联系方式信息。本…

python-计算两个矩阵的相似度。

余弦相似度 在pytorch中&#xff0c;有一个专门的函数用于计算相似度&#xff1a;torch.cosine_similarity() https://pytorch.org/docs/stable/nn.functional.html#cosine-similarity import torch import torch.nn.functional as F input1 torch.randn(100, 128) input2 t…

【2023,学点儿新Java-32】Java基础小练习:根据圆周率与半径求圆的面积 | 温度转换 | 计算矩形面积 | 判断奇偶数 | 年龄分类

前情提要&#xff1a; 【2023&#xff0c;学点儿新Java-31】测试&#xff1a;整型和浮点型变量的使用 | 附&#xff1a;计算机存储单位&#xff08;转换关系&#xff09;| 企业真题&#xff1a;为什么0.10.2不等于0.3【2023&#xff0c;学点儿新Java-30】变量的基本使用&#…

回归预测 | MATLAB实现WOA-CNN-BiGRU鲸鱼算法优化卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现WOA-CNN-BiGRU鲸鱼算法优化卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-CNN-BiGRU鲸鱼算法优化卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 回归预测 | MATLAB实…

安全不“放假”,VR安全教育等你沉浸式体验

暑期开启&#xff0c;孩子们将迎来一段丰富且快乐的时光&#xff0c;暑假虽快乐&#xff0c;但是安全不能“放假”&#xff0c;许多地方开展形式多样的暑假安全宣传活动&#xff0c;想不想沉浸式体验下VR安全教育宣传呢&#xff1f;通过VR演示&#xff0c;身临其境的了解防溺水…

MySQL-概述-数据模型SQL简介

数据库&#xff1a;DataBase&#xff08;DB&#xff09;&#xff0c;是存储和管理数据的仓库数据库管理系统&#xff1a;DataBase Management System&#xff08;DBMS&#xff09;&#xff0c;操作和管理数据库的大型软件。SQL&#xff1a;Structured Query Language&#xff0…

「提高你的CSS技能」:15个重要的CSS属性详解

这篇文章介绍了15个重要的CSS属性&#xff0c;旨在提高读者的CSS知识和技能。文章以清晰的方式解释了每个属性的作用和用法&#xff0c;并提供了相应的示例代码。通过这篇文章&#xff0c;读者可以了解到一些有趣且实用的CSS属性。 1:in-range 和:out-of-range 伪类 CSS的:in…

KafKa 3.x(三、Eagle、Kraft、压测调优,源码解析)

6. Kafka-Eagle监控 Kafka-Eagle框架用于监控Kafka集群运行状况。官网https://kafka-eagle.org 6.1 Mysql 前置mysql。 6.2 Kafka环境 关闭集群 kf.sn stop修改vim /bin/kafka-server-start.sh 并同步到其他节点 if [ "x$KAFKA_HEAP_OPTS" "x" ]; t…

vue使用html2canvas实现一键截图并赋值到剪贴板,只截取当前显示器上可视的内容

使用html2canvas 和 clipboard API实现整页截图并填充至剪切板。 访问剪切板的api只支持在https或者本地localhost上使用&#xff0c;如果是http&#xff0c;则无法使用 首先需要从npm安装html2canvas npm install html2canvas然后在代码中导入这个包&#xff1a; import ht…

git安装教程

前言 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从小到大的项目版本管理。下面详细的用图文形式介绍一下git安装过程&#xff08;记录一下git安装过程供参考&#xff09; 一、下载git 打开git官网地址&#xff1a;https://git-scm.com/进行下载&am…

适合宝妈和学生党的副业,在家就可以做的兼职,实现高质量躺平

如果工资不够高&#xff0c;那就会让人过得很拮据。因此&#xff0c;很多人都希望可以通过兼职或副业来增加收入。然而&#xff0c;找到可靠的副业却并不容易&#xff0c;还会面临各种困难。 跟大家介绍七种可行的兼职副业&#xff0c;希望能为那些想增加收入的职场人员提供一…

第四章:DeepLabV2——使用深度卷积神经网络、空洞卷积和全连接条件随机场进行语义图像分割

0.摘要 在这项工作中&#xff0c;我们使用深度学习来解决语义图像分割任务&#xff0c;并做出了三个实验证明具有实际价值的主要贡献。 首先&#xff0c;我们强调通过上采样滤波器进行卷积&#xff0c;或者称为“空洞卷积”&#xff0c;在密集预测任务中是一种强大的工具。空洞…

Langchain-ChatGLM配置文件参数测试

1 已知可能影响对话效果的参数&#xff08;位于configs/model_config.py文件&#xff09;&#xff1a; # 文本分句长度 SENTENCE_SIZE 100# 匹配后单段上下文长度 CHUNK_SIZE 250 # 传入LLM的历史记录长度 LLM_HISTORY_LEN 3 # 知识库检索时返回的匹配内容条数 VECTO…

谈谈你对 binder 的理解?

面试官提了一个问题&#xff0c;我们来看看 &#x1f60e;、&#x1f628; 和 &#x1f914;️ 三位同学的表现如何吧 &#x1f60e; 自认为无所不知&#xff0c;水平已达应用开发天花板&#xff0c;目前月薪 10k 面试官️&#xff1a;谈谈你对 binder 的理解 &#x1f60e;&a…