首页 > 编程语言 >突破编程_C++_网络编程(OSI 七层模型(传输层))

突破编程_C++_网络编程(OSI 七层模型(传输层))

时间:2024-03-31 21:29:34浏览次数:34  
标签:UDP 编程 TCP C++ 传输层 数据传输 数据 连接

1 传输层的功能与特点

1.1 传输层的功能

传输层是 OSI 七层模型中的第四层,它位于网络层和应用层之间,起着承上启下的关键作用。以下是关于 OSI 传输层功能的详细讲解:

一、提供可靠的数据传输服务

传输层的主要任务是确保数据在源主机和目标主机之间可靠地传输。它通过一系列机制来确保数据的完整性、顺序性和正确性。

  • 差错控制:传输层会对传输的数据进行差错检测,如果检测到数据错误或丢失,会采取适当的措施,如请求重传,以恢复数据的完整性。
  • 流量控制:传输层会控制数据的发送速率,避免发送方发送数据过快而导致接收方无法及时处理。这有助于防止网络拥塞和数据丢失。
  • 序列号与确认机制:传输层会为每个数据段分配一个唯一的序列号,并在接收端进行确认。这确保了数据的顺序性和完整性,即使在网络中发生乱序或丢包的情况,也能通过重新排序或重传来恢复数据的正确顺序。

二、复用与分用功能

传输层还具有复用和分用的功能,这使得多个应用层进程可以同时使用传输层的服务,并且能够将接收到的数据准确地交付给相应的应用层进程。

  • 复用:多个应用层进程可以使用同一个传输层连接来发送和接收数据。传输层通过端口号来区分不同的应用层进程,实现了多个应用层进程之间的并行通信。
  • 分用:传输层在接收到数据后,会根据端口号将数据分发给相应的应用层进程。这样,每个应用层进程都能接收到属于自己的数据,实现了数据的正确交付。

三、连接管理

对于面向连接的协议(如 TCP),传输层还负责建立、维护和终止连接。

  • 连接建立:在数据传输之前,传输层会进行三次握手来建立连接。这确保了双方都已准备好进行数据传输,并协商了一些参数(如最大发送窗口大小等)。
  • 连接维护:在数据传输过程中,传输层会持续监控连接的状态,确保数据的可靠传输。如果检测到连接中断或错误,会采取相应的措施进行恢复或重新建立连接。
  • 连接终止:当数据传输完成后,传输层会进行四次挥手来优雅地关闭连接。这确保了双方都已正确处理完所有数据,并释放了相关的资源。

四、支持不同的传输服务类型

传输层还支持不同的传输服务类型,以满足不同应用的需求。例如,它可以提供面向连接的可靠传输服务(如 TCP),也可以提供无连接的不可靠传输服务(如 UDP)。这使得传输层能够灵活地适应各种应用场景的需求。

1.2 传输层的特点

以下是 OSI 传输层的一些主要特点:

  • 可靠性:传输层通过差错控制机制确保数据的可靠性。它使用各种技术,如校验和、确认和重传机制,来检测并纠正数据在传输过程中可能出现的错误。这种可靠性保证对于许多应用来说是至关重要的,尤其是那些对数据传输准确性有严格要求的应用。

  • 复用与分用:传输层具有复用和分用的功能。复用允许多个应用层进程同时使用同一个传输层连接进行通信,而分用则负责将接收到的数据准确地交付给相应的应用层进程。这种机制使得传输层能够高效地处理来自多个应用的数据流,并实现了数据的正确分发。

  • 流量控制:传输层通过流量控制机制来避免网络拥塞和数据丢失。它根据接收方的处理能力来调整发送方的数据发送速率,确保数据在网络中的平稳流动。这种流量控制有助于维护网络的稳定性和性能。

  • 连接管理:对于面向连接的协议(如 TCP),传输层负责建立、维护和终止连接。它通过一系列握手过程来建立连接,并在数据传输完成后通过相应的挥手过程来关闭连接。这种连接管理机制确保了数据传输的连续性和安全性。

  • 支持多种传输服务:传输层可以支持多种不同的传输服务,包括可靠的、面向连接的传输服务(如 TCP)和不可靠的、无连接的传输服务(如 UDP)。这种灵活性使得传输层能够适应各种不同的应用需求和网络环境。

  • 独立性:在 OSI 模型中,传输层与其他层次相互独立,层次之间的变化不会对其他层次产生影响。这种独立性使得网络的设计更加灵活,可以针对不同的需求进行定制和优化。

2 TCP 协议

2.1 TCP 协议的工作原理

TCP 协议工作原理,主要围绕着确保数据的可靠传输而展开。它采用了一系列复杂的机制,包括连接建立、数据传输、流量控制、拥塞控制以及连接终止等,以确保数据在网络中能够安全、准确地到达目的地。

首先,我们来看TCP协议如何建立连接。这一过程通常被称为“三次握手”。

(1)连接建立(三次握手):

  • 第一次握手:客户端向服务器发送一个 SYN 报文段,其中包含客户端的初始序列号。这一步骤表示客户端请求与服务器建立连接。
  • 第二次握手:服务器收到 SYN 报文段后,回复一个 SYN+ACK 报文段给客户端。这个报文段中包含了服务器的初始序列号以及对客户端 SYN 报文段的确认。
  • 第三次握手:客户端收到服务器的 SYN+ACK 报文段后,再发送一个 ACK 报文段给服务器,确认已收到服务器的初始序列号。至此,三次握手完成,TCP 连接建立成功。

接下来是数据传输阶段。

(2)数据传输:

  • TCP 协议将数据分成小的报文段进行传输。每个报文段都包含序列号,以确保接收端能够按正确的顺序重新组装数据。
  • TCP 采用全双工通信模式,即数据可以在两个方向上同时传输。
  • 发送方每发送一个报文段后,都会等待接收方的确认(ACK)。如果发送方在一段时间内未收到确认,它会重发该报文段,以确保数据的可靠传输。

在数据传输过程中,TCP 还采用了流量控制和拥塞控制机制。

(3)流量控制:

TCP 利用滑动窗口机制来实现流量控制。接收方会在每个 ACK 报文段中告诉发送方自己当前的接收窗口大小,即还能接收多少数据。发送方根据这个窗口大小来调整自己的发送速率,避免发送过快导致接收方处理不及。

(4)拥塞控制:

当网络出现拥塞时,TCP会采取一系列措施来降低发送速率,减少数据传输量,以缓解网络拥塞。这包括慢开始、拥塞避免、快重传和快恢复等算法。
最后,当数据传输完成后,TCP会进行连接终止操作。

(4)连接终止(四次挥手):

  • 第一次挥手:客户端向服务器发送一个 FIN 报文段,表示数据已发送完毕,请求关闭连接。
  • 第二次挥手:服务器收到 FIN 报文段后,回复一个 ACK 报文段给客户端,确认收到 FIN 请求。
  • 第三次挥手:服务器完成数据传输后,也发送一个 FIN 报文段给客户端,表示服务器也请求关闭连接。
  • 第四次挥手:客户端收到服务器的 FIN 报文段后,回复一个 ACK 报文段给服务器,确认收到服务器的关闭请求。至此,四次挥手完成,TCP 连接关闭。

在整个过程中,TCP 协议通过复杂的机制确保了数据的可靠传输。无论是建立连接、传输数据还是终止连接,TCP都采取了一系列措施来确保数据的完整性、顺序性和准确性。这使得TCP成为许多应用的首选传输协议,尤其是在那些对数据传输可靠性有严格要求的应用场景中。

2.2 TCP 协议的主要特点

OSI 传输层的 TCP 协议的主要特点体现在其可靠性、面向连接、流量控制、拥塞控制以及字节流服务等方面。以下是关于这些特点的详细讲解:

一、可靠性

TCP协议以其高度的可靠性而著称。它通过以下机制确保数据的可靠传输:

  • 序列号与确认机制:TCP 为每个发送的数据包分配一个唯一的序列号,并在接收端进行确认。接收端在收到数据包后会回复一个确认(ACK)报文段,告知发送端已成功接收。如果发送端在一定时间内未收到确认,会重传该数据包。
  • 重传机制:当数据包丢失或出错时,TCP 会重传丢失的数据包,直到接收端正确接收为止。这种机制确保了数据的完整性和准确性。
  • 校验和:TCP 在发送数据前会计算数据的校验和,并在接收端进行校验。如果校验和不匹配,接收端会要求发送端重传数据。

二、面向连接

TCP 是一种面向连接的协议,它在数据传输之前必须先建立连接。这种连接方式使得 TCP 能够提供更为可靠和有序的数据传输服务。连接建立过程通过三次握手完成,确保了双方都已准备好进行数据传输。在数据传输过程中,TCP 会维护连接状态,并在数据传输完成后通过四次挥手来优雅地关闭连接。

三、流量控制

TCP 协议具有流量控制功能,它能够根据接收方的处理能力来调整发送方的发送速率。这主要通过滑动窗口机制实现。接收方会在每个确认报文段中告诉发送方自己当前的接收窗口大小,即还能接收多少数据。发送方根据这个窗口大小来调整自己的发送速率,避免发送过快导致接收方处理不及。这种流量控制机制有助于维护网络的稳定性和性能。

四、拥塞控制

TCP 协议还具有拥塞控制功能,它能够根据网络状况调整数据传输速率,防止网络拥塞。当网络出现拥塞时,TCP 会采取一系列措施来降低发送速率和减少数据传输量,以缓解网络拥塞状况。这包括慢开始、拥塞避免、快重传和快恢复等算法。这些算法使得TCP能够在不同网络条件下保持较高的传输效率。

五、字节流服务

TCP 提供的是字节流服务,这意味着它将应用程序发送的数据视为无结构的字节流。TCP 不关心应用程序发送的数据的边界,而是将其拆分成大小合适的报文段进行传输。在接收端,TCP 会按照正确的顺序重新组装这些报文段,并交付给应用程序。这种字节流服务使得 TCP能够灵活地处理各种类型的数据传输需求。

3 UDP 协议

OSI 传输层的 UDP 协议(用户数据报协议)是一种无连接的、不可靠的传输协议,它主要用于应用程序之间的数据报通信。与 TCP 协议不同,UDP 协议不建立和维护连接,也不提供数据流的可靠传输和顺序保证。

(1)工作原理

  • 数据报格式:

UDP 数据报由两个重要字段组成:源端口号和目的端口号。端口号指明了数据是从哪个应用程序发送到哪个应用程序。此外,UDP 数据报还包含长度和校验和等字段,用于确保数据的完整性和准确性。

  • 无连接性:

UDP 是一种无连接的协议,即发送方和接收方之间在数据传输之前不需要建立连接。发送方可以随时发送数据报,而接收方也可以随时接收数据报。这种无连接性使得 UDP 协议的开销较小,传输效率较高。

  • 不可靠性:

UDP 协议不保证数据的可靠传输和顺序性。发送方不会等待接收方的确认,而是连续发送数据报。如果某个数据报在传输过程中丢失或损坏,接收方将无法得知,也无法请求重传。因此,UDP 协议适用于那些对数据传输的可靠性要求不高,但对实时性要求较高的应用场景。

  • 尽力交付:

UDP 协议采用尽力交付的方式,即发送方只负责尽力地将数据报传输给接收方,而不保证接收方是否正确接收。这种机制使得UDP协议在传输过程中的开销较小,传输更加高效。

  • 广播和多播支持:

UDP 协议支持广播和多播功能。广播是指一个 UDP 数据报可以同时发送给所有网络中的设备;多播则是指一个 UDP 数据报可以同时发送给多个目的地址。这种功能使得 UDP 协议在一些特定的应用场景(如局域网内的通知广播)中非常有用。

(2)应用场景

由于 UDP 协议具有简单、高效、实时性好的特点,它常被用于一些对数据传输可靠性要求不高,但对实时性要求较高的应用场景。例如:

  • 实时音视频传输:在视频会议、在线直播等应用中,需要实时传输音视频数据。由于音视频数据本身具有一定的容错性,且对实时性要求较高,因此 UDP 协议是一个很好的选择。
  • 网络游戏:在网络游戏中,玩家之间的实时交互非常重要。使用UDP协议可以确保数据的快速传输,提高游戏的响应速度和流畅度。
  • DNS 查询:DNS 查询过程中,客户端向 DNS 服务器发送查询请求,并等待服务器的响应。由于 DNS 查询的实时性要求较高,且查询结果通常较小,因此 UDP 协议是一个合适的选择。

需要注意的是,虽然UDP协议在某些场景下具有优势,但在需要保证数据传输可靠性和顺序性的应用中,还是应该选择TCP协议。在实际应用中,应根据具体需求选择合适的传输协议。

4 TCP 协议与 UDP 协议的对比

OSI 传输层的 TCP 协议和 UDP 协议是两种截然不同的传输协议,它们各自具有独特的特性和适用场景:

首先,TCP 协议是一种面向连接的协议,它在数据传输之前需要建立连接。这种连接方式使得 TCP 能够提供可靠的数据传输服务,确保数据的完整性和顺序性。而 UDP 协议则是一种无连接的协议,发送方和接收方之间不需要建立连接即可进行数据传输。这种无连接性使得 UDP 的开销较小,传输效率较高。

其次,TCP 协议提供了流量控制和拥塞控制机制。流量控制通过滑动窗口机制来限制发送方的发送速率,确保接收方能够及时处理接收到的数据。而拥塞控制则根据网络状况来调整发送速率,以避免网络拥塞。这些机制使得 TCP 能够在网络状况不佳时仍然保持较高的传输效率。相比之下,UDP 协议没有这些控制机制,它只管发送数据,不关心网络状况和数据是否到达。

在可靠性方面,TCP 协议通过确认、重传等机制来保证数据的可靠传输。如果发送方在一定时间内未收到接收方的确认,它会重传数据,直到接收方正确接收为止。这种可靠性使得 TCP 适用于那些对数据传输可靠性要求较高的应用场景。而 UDP 协议则不提供可靠传输保证,发送方发送数据后不会等待确认,数据可能会丢失或乱序。因此,UDP 适用于那些对实时性要求较高,但对数据可靠性要求不高的场合。

此外,UDP 协议还具有首部开销小的特点。其报文首部只有 8 个字节,比TCP的 20 个字节小得多。这减少了每个数据包的开销,使得 UDP 在传输大量小数据包时更加高效。然而,这种高效性也带来了一定的局限性,因为 UDP 无法处理复杂的网络情况,如丢包、乱序等问题。

在应用场景上,TCP 协议广泛应用于需要保证数据传输可靠性和顺序性的场合,如文件传输、电子邮件等。而 UDP 协议则适用于那些对实时性要求较高,但对数据可靠性要求不高的场合,如实时音视频传输、网络游戏等。

5 端口的概念与作用

(1)概念

端口,在计算机科学和网络通信中,是一个抽象的概念,可以理解为计算机与外界通信交流的出口。它不仅是数据传输的通道,也是应用程序或服务的标识。在OSI模型中,传输层负责提供端到端的数据传输服务,而端口则是传输层实现这一功能的关键组件。

端口的起源可以追溯到计算机网络发展的早期。随着计算机网络的普及和应用程序的增多,如何确保数据能够准确地到达目标应用程序成为了一个重要的问题。端口的概念应运而生,它为每个应用程序或服务提供了一个唯一的标识,使得数据能够在复杂的网络环境中被正确地路由和传递。

(2)作用与功能

  • 应用程序标识:在网络通信中,每个应用程序或服务都需要一个唯一的标识,以便在接收数据时能够准确地识别出是哪个应用程序发送的。端口号就是这样一个标识,它使得不同的应用程序可以通过不同的端口号进行区分。这样,当数据到达主机时,操作系统可以根据数据包中的目标端口号,将数据转发给相应的应用程序进行处理。

  • 数据转发:端口不仅用于标识应用程序,还负责数据的转发。当数据从源主机发送到目标主机时,目标主机会根据数据包中的目标端口号将数据转发给相应的应用程序。这个过程确保了数据能够准确地到达目标应用程序,实现了数据的正确传递。

  • 安全性保障:端口还可以用于安全性控制。通过配置防火墙或安全策略,可以限制对特定端口的访问,从而防止未经授权的访问和数据泄露。例如,可以关闭不必要的端口,以减少潜在的攻击面;或者对特定端口进行访问控制,只允许特定的IP地址或用户访问。

  • 多路复用:在网络通信中,一台主机上可能有多个应用程序同时运行,并且这些应用程序都需要与网络进行通信。通过为每个应用程序分配一个或多个端口,可以实现多个应用程序同时进行网络通信,提高了网络资源的利用效率。这种能力被称为多路复用。

(3)分类与编号

端口号是一个用于标识端口的数字。根据端口号的不同,端口可以分为以下几类:

  • 熟知端口(Well-Known Ports):这些端口号从 0 到 1023,由 IANA(Internet Assigned Numbers Authority)分配,并保留给特定的系统服务使用。这些服务通常是非常重要的,且在网络通信中扮演着关键角色。例如,HTTP服务的端口号为80,HTTPS 服务的端口号为443,FTP 服务的端口号为 21 等。由于这些端口号被广泛认知和使用,因此被称为熟知端口。

  • 注册端口(Registered Ports):这些端口号从 1024 到 49151,可以由用户或组织向 IANA 申请注册,用于特定的应用程序或服务。这些端口号通常用于那些不是系统级服务的应用程序,但仍然需要在网络中进行通信。注册端口的使用需要遵循一定的规范和流程,以确保不会与现有的服务或应用程序发生冲突。

  • 动态端口或私有端口(Dynamic or Private Ports):这些端口号从 49152 到 65535,是临时分配的,通常用于不需要固定端口的应用程序或服务。动态端口的使用更加灵活,可以根据需要进行分配和调整。然而,由于这些端口号可能被多个应用程序或服务同时使用,因此在使用时需要特别注意避免冲突。

(4)绑定特定端口的代码示例

下面是一个简单的 C++ 代码示例,展示了如何在 Windows 系统中使用套接字 API 创建一个 TCP 服务器,该服务器绑定到特定的端口,并等待客户端的连接。

#include <winsock2.h>  
#include <ws2tcpip.h>  
#include <iostream>  
#pragma comment(lib, "ws2_32.lib")  

int main() {
	WSADATA wsaData;
	int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (result != 0) {
		std::cerr << "WSAStartup failed: " << result << std::endl;
		return 1;
	}

	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (serverSocket == INVALID_SOCKET) {
		std::cerr << "socket creation failed" << std::endl;
		WSACleanup();
		return 1;
	}

	sockaddr_in serverAddr;
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_addr.s_addr = INADDR_ANY; // Listen on any IP address  
	serverAddr.sin_port = htons(12345); // Bind to port 12345  

	if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
		std::cerr << "bind failed" << std::endl;
		closesocket(serverSocket);
		WSACleanup();
		return 1;
	}

	if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
		std::cerr << "listen failed" << std::endl;
		closesocket(serverSocket);
		WSACleanup();
		return 1;
	}

	std::cout << "Server is listening on port 12345..." << std::endl;

	SOCKET clientSocket;
	sockaddr_in clientAddr;
	int clientAddrSize = sizeof(clientAddr);

	clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrSize);
	if (clientSocket == INVALID_SOCKET) {
		std::cerr << "accept failed" << std::endl;
		closesocket(serverSocket);
		WSACleanup();
		return 1;
	}

	std::cout << "Client connected!" << std::endl;

	closesocket(clientSocket);
	closesocket(serverSocket);
	WSACleanup();

	return 0;
}

这个示例代码创建了一个 TCP 服务器,它绑定到端口 12345 并等待客户端的连接。一旦有客户端连接,它就会输出一条消息并关闭连接。在实际应用中,一般会在 accept 之后添加代码来处理客户端发送的数据,并使用循环来接受多个客户端的连接。

标签:UDP,编程,TCP,C++,传输层,数据传输,数据,连接
From: https://blog.csdn.net/h8062651/article/details/137208762

相关文章

  • 理解 Python 编程中 *args 与 **kwargs 的妙用
    文章目录一、形式参数与实际参数二、*args与**kwargs三、总结......
  • 06 面向对象编程 (续)
    Static关键字静态代码块:只执行一次。Person.javapackagecom.mysoft.oop.demo08;publicclassPerson{//2:赋初值{System.out.println("匿名代码块");}//1:只执行一次static{System.out.println("静态代码块");}//......
  • 【C++实验1】学生成绩信息管理系统题解
    【问题描述】编写一个基于结构体得学生成绩信息管理系统。主要功能如下:1.用结构体存放所有数据。2.每个功能都用函数实现。3.输入10个学生的学号和三门课程的成绩。4.计算每个学生的总分。5.按总分从高到低排序。6.加上名次一列。7.输出最后的二维表格样式的成......
  • C++--STL函数模板
    一.函数模板我们可以定义一个函数模板(functiontemplate),而不是为每个类型都定义一个函数。一个函数模板就是一个蓝图,可用来生成针对特定类型的函数。例如用于比较两个数字的大小compare()函数的模板如下:template<typenameT>intcompare(constT&v1,constT&v2){......
  • C++初阶篇----内存管理
    目录引言1.内存分布2.C动态内存管理方式:malloc/calloc/realloc/free3.C++动态内存管理:new和delete3.1内置类型3.2自定义类型4.operatornew与operatordelete函数4.1operatornew与operatordelete函数5.new和delete的实现底层5.1内置类型5.2自定义类型引......
  • C++ 引用传递 超级详细 小白也行
    一.引用的概念引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(本名和小名共用一块地址)例如:就像是给你取小名,本名小名都是你,所有作用也都一样。 类型&引用变量名(对象名)=引用实体(如图下)......
  • Springboot 实现Aop切面编程
    1.引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency> 2.写切面方法现在有个方法,publicList<User>getList(){List<User>users=......
  • 便民查询 - C++也能写H5应用
    这款应用是我和我的一位粉丝共创,他还在读大二,刚学了C++,他一直都想找个靠谱的项目练练手,刚好我准备做一款便民查询的应用,当然这个应用如果用C++来写后端,会有一种大炮打蚊子的感觉,C++也不适合做APP开发,开发效率和debug容易度都比其他的高级语言差一截。但是由于他想找个项目练手,我......
  • C++ vector
    文章目录vector的介绍vector介绍vector的定义vectoriterator的使用vector空间增长问题vector的增删查改vector的模拟实现创建vector类和成员变量iterator迭代器范围for构造函数赋值、析构空间容量resize和reserve的区别下标操作符重载插入删除交换vector深度剖析v......
  • C++中Switch穿透的妙用
    在C++中,Case穿透(fall-through)指的是在switch语句中,一个case标签没有显式地使用break语句来终止,而是直接执行下一个case标签中的代码。虽然Case穿透在编程中有时会被视为不良实践,因为它可能导致代码的可读性变差和潜在的错误,但有时也可以利用它来实现一些特定的目的。以下是一些利......