前言
在Linux中,如果只是想进行本地通信,我们可以使用Linux提供的多种IPC机制,包括管道、消息队列、共享内存和信号等。这些机制允许在同一台计算机上的进程之间传递数据和通信。但是如果我们想进行远距离跨网络的通信,又该如何解决呢?Linux网络编程就可以实现这样的通信,其中涉及许多接口以及概念,因此本篇文章便是对这些概念先进行介绍。
网络协议
网络协议就像是我们在交谈时使用的一套规定和礼仪。可以想象一下,如果你和一个陌生人交谈,你们需要共同遵守一些约定以便能够i顺利交流。网络协议也是类似的,它们是计算机间通信的规则集,确保不同设备能理解和相互交流。举个例子,想象你用一种语言说话,而另一个人却只懂另一种语言。如果没有翻译或共同的语言,你们将无法有效交流。而网络协议则是提供了一种共同的语言,让不同设备之间能够彼此理解和交流。此外,网络协议也包括一些规则,比如在对话中何时开始和结束、如何处理丢失的信息等等。这就像在谈话中的礼仪,比如等待别人说完再回答,或者当你没有听清楚时请求对方重复。
总的来说,网络协议是一种约定或规范,用于定义在计算机网络中数据如何传输、路由和接收的方式。这些协议规定了通信设备之间的通信规则,包括数据格式、错误检测和纠正、数据的分段和重组、数据的传输速率等等。网络协议可以被看作是一种通信语言和协商的方式,确保不同的计算机和网络设备能够有效地交换信息。这些协议确保了数据的可靠性、完整性和安全性,同时允许不同厂商的设备协同工作,就像各种不同的电话可以相互通话,而不仅仅局限于同一个制造商的产品。
在我们的计算机网络中,最重要的协议包括IP、TCP、UDP等,它们构成了互联网的基础,允许数据在全球范围内传输和交换。它们使得我们能够在今天的互联网世界中实现广泛的通信和数据传输。
IP地址
IP地址(Internet Protocol address)是Internet协议(IP)中用于给主机分配的标识号码。它是网络上每一个设备的唯一标识,用于在互联网上定位和识别设备。IP地址的版本分为IPv4和IPv6。其中最常用的版本为IPv4,该版本由32位组成,通常以四个十进制数字分隔的形式表示,每个数字范围从0到255。例如:192.168.1.1。而IPv6是为了应对IPv4地址耗尽的问题开发出来,IPv6使用128位地址,通常以八组四位十六进制数表示。例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334。其中IP地址的类型有分为公有IP地址和私有IP地址,公有IP地址在互联网上是唯一的,用于互联网上的设备通信。私有IP地址仅在私有网络(例如家庭或公司网络)中使用,并不在互联网上公开。因此它们在不同的私有网络中可能会重复。IP地址也分为静态与动态,静态IP地址是手动配置并固定不变的。动态IP地址是由网络服务(如DHCP)自动分配的,并可能会随时间改变。IP地址中有存在一批特殊地址,如环回地址127.0.0.1(IPv4)或::1(IPv6),用于设备自我测试。广播地址用于向网络上的所有设备发送消息。子网广播地址用于向子网内的所有设备发送消息。
由此,IP地址使得设备能够在互联网上彼此通信。当你访问一个网站或向另一个计算机发送信息时,你的计算机使用IP地址来找到并通信与目标计算机或服务器。
源IP地址和目的IP地址
在计算机网络中,当数据包在网络上进行传输时,它通常包含IP地址的,IP地址又分为源IP地址和目的IP地址,这两个地址提供了数据包的出发点和目的地的信息。
其中源IP地址包含了发送数据包的设备的IP地址。当一个设备(例如计算机、手机或服务器)想要发送数据到网络上的另一个设备时,它会在数据包中附上自己的IP地址作为源IP地址。这样,接收设备可以知道数据包来自哪里,并可能需要根据需要向源地址发送回复。目的IP地址包含了数据包应该送达的设备的IP地址。当设备发送数据时,它指定数据包应该传送到的目的地的IP地址。路由器和其他网络设备使用这个地址来确定如何将数据包正确地路由到其最终目的地。
在一个典型的网络交互中,源设备的源IP地址和目的设备的目的IP地址在数据包交换过程中都起到了关键作用。如果目的设备需要回复,它可以使用原始数据包中的源IP地址作为其数据包的目的IP地址,这确保了通信的双向性和连续性。
MAC地址
MAC地址,全称为“媒体访问控制地址”(Media Access Control Address),是一个分配给网络接口卡(NIC,也称为以太网卡或网卡)的唯一标识符。它通常用于局域网(LAN)内的通信,尤其是在以太网和Wi-Fi网络中。MAC地址通常由6个字节(48位)组成,以16进制表示,例如:00:1A:2B:3C:4D:5E。全球范围内,每个MAC地址应该是唯一的。前三个字节(也被称为"组织唯一标识符"或OUI)是由IEEE分配给硬件制造商的,确保全球范围内的唯一性。后三个字节是由制造商自行分配的,确保在该制造商生产的所有设备中的唯一性。与IP地址不同(IP地址可以更改并根据网络配置分配给任何设备),MAC地址是硬编码到网络接口卡中的,通常称为设备的“物理地址”。在局域网内,设备之间的通信是基于MAC地址的。例如,ARP(地址解析协议)就是用来在已知IP地址的情况下查找相应的MAC地址。考虑到隐私问题,现代Wi-Fi设备在扫描网络时通常会使用随机MAC地址,这样可以避免用户的跟踪。尽管每个网络接口卡都有一个固定的、硬编码的MAC地址,但大多数现代操作系统允许用户更改或“欺骗”MAC地址。这在某些场景中是有用的,但也可能被用于恶意目的。
总之,MAC地址是网络设备在物理网络中的唯一标识符,允许数据包在本地网络中正确地路由到目的地。
端口号
端口号是计算机网络中用于标识特定网络服务或应用程序的数字,它是一个2字节16位的整数。它们通常与IP地址一起使用,以确定数据包应该被路由到哪个应用程序或服务。端口号范围从0到65535,分为三个主要类别:
-
知名端口:这些端口号范围从0到1023,通常用于标准化的网络服务,如HTTP(端口号80)、HTTPS(端口号443)、FTP(端口号21)、SMTP(端口号25)等。操作系统和网络设备通常会预留这些端口号以提供这些基本服务。
-
注册端口:这些端口号范围从1024到49151,用于用户或应用程序定义的服务。许多应用程序和服务选择在这个范围内分配端口号。
-
动态或私有端口:这些端口号范围从49152到65535,通常由操作系统分配给客户端应用程序,以便它们可以临时使用,而不与其他应用程序冲突。
端口号允许多个应用程序在同一台计算机上共享相同的IP地址,因为数据包可以根据目标端口号被路由到正确的应用程序。这是计算机网络中实现多任务和多应用程序通信的关键机制。因此在网络通信中可以使用IP地址加端口号来确定网络中的一台唯一主机的唯一进程。
端口号与进程ID
在知道了端口号和进程ID都是用来确定进程的,那么为什么不使用进程ID,而是单独搞一套端口号呢?要知道其实使用进程ID也是可以的,在操作系统级别,进程ID是用来唯一标识一个运行中的进程的,每个进程都有一个唯一的PID,这个标识符在本地计算机内是独一无二的。然而,在网络通信中,要在不同的计算机之间唯一标识一个进程,单独使用PID是不够的。因为在不同主机上的进程可能具有相同的PID,因为PID是在每台计算机上独立分配的。在网络中,我们需要一个全局唯一的标识符。将PID暴露在网络中可能会引发安全隐患,恶意用户可以利用这些信息进行攻击或者进行其他不当操作。并且操作系统可能会重新分配PID,例如,当一个进程终止后,下一个新启动的进程可能会获得之前终止进程的PID,这会导致混淆和错误。
因此,如果想复用进程ID的话就还需要添加一些标识位来进行区分,既然都添加了标识位了,那么为什么不直接重新搞一套呢?因此在网络通信中,使用IP地址和端口号的组合来唯一标识网络上的进程或服务是一种更可靠、安全、并且具有全局唯一性的做法。这样可以确保不同主机之间的进程能够被唯一标识,而不会受到操作系统内部的变化影响。
源端口和目的端口
在网络通信中,端口号也分为源端口号和目的端口号,源端口号和目的端口号是用于标识通信中的发送方和接收方的端口号。它们是TCP和UDP等协议中的一部分,用于确保数据正确传输到正确的进程或服务。其中,源端口号指的是发送方的端口号。它是通信中数据包的起始点。当你的计算机向另一台计算机发送数据时,你的计算机会选择一个临时的源端口号,用于标识数据流的来源。目的端口号是接收方的端口号。它用于确定数据包应该传递到接收方的哪个进程或服务。目的端口号是接收方用来识别要传递的数据应该被哪个进程接收的关键信息。
这种双端口的机制允许多个进程或服务同时在同一台计算机上运行,并且同时与其他计算机进行通信,因为每个数据包都可以通过源端口和目的端口来精确地路由到正确的进程。这样,不同的进程可以在同一主机上使用相同的IP地址,但通过不同的端口号来实现通信,确保数据包能够传递到正确的接收方。
协议
TCP协议
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层协议。它确保了数据的可靠传输,被广泛用于互联网上的应用,如网页浏览、电子邮件、文件传输等。TCP协议的主要特点和功能包括如下几点:
-
可靠性: TCP使用确认机制来确保数据的可靠传输。接收方会发送确认消息来告知发送方数据已经收到,如果发送方在一定时间内没有收到确认,则会重传数据,确保数据不会丢失或损坏。
-
面向连接: 在数据传输之前,发送方和接收方需要建立一个连接。连接的建立和断开是通过“三次握手”和“四次挥手”来完成的,这样可以确保双方都准备好进行数据传输。
-
流量控制: TCP协议可以根据接收方的处理能力动态调整发送数据的速率,以防止数据的过载和丢失。
-
拥塞控制: TCP能够检测网络拥塞的情况,并采取相应的措施,例如减缓数据传输速率,以避免网络拥塞导致的数据丢失和延迟。
-
顺序保证: TCP会确保数据按照发送的顺序到达接收方,这样接收方能够正确重构发送方发送的数据流。
-
全双工通信: TCP允许双方在同一时间进行数据的发送和接收,实现了全双工通信。
总的来说,TCP协议提供了一种可靠、有序、面向连接的数据传输方式,适用于需要可靠数据传输的应用场景。然而,由于它的可靠性和连接管理的开销,它的传输速度相对于UDP等无连接的协议可能较慢。所以在选择协议时,需要根据应用的需求权衡各种因素。
UDP协议
UDP(User Datagram Protocol)是一种网络协议,它位于OSI模型的传输层,用于在计算机网络上以无连接的方式传输数据。UDP协议的一些重要特点包括如下几点:
-
无连接性:UDP是一种无连接协议,这意味着在数据传输过程中不建立或维护持久的连接。每个UDP数据包都是独立的,不会像TCP一样建立连接和维持状态信息。
-
不可靠性:UDP不提供数据包的可靠性传输。这意味着数据包可能会丢失、重复、顺序错乱或损坏,而协议本身不提供机制来处理这些问题。UDP更适合那些对数据丢失不敏感的应用,例如实时音视频流。
-
低开销:UDP协议的头部相对较小,不像TCP那样需要大量的控制信息和状态维护。这使得UDP在一些对传输延迟非常敏感的应用中表现出色,如在线游戏和语音通信。
-
高性能:由于UDP的简单性和低开销,它通常比TCP更快速。这使得它适合需要高性能的应用,但在网络不稳定或拥塞时可能会导致数据包丢失。
UDP通常用于那些能够容忍一些数据包丢失而且需要低延迟的应用,例如实时多媒体流、DNS查询、网络游戏和传感器数据传输。总之,UDP是一种简单而快速的协议,适合特定类型的应用,但需要应用层自身来处理数据可靠性和顺序性等问题。如果应用需要可靠的数据传输,通常会选择使用TCP协议。
TCP协议与UDP协议
值得注意的是,UDP协议是一种面向数据报的协议。这意味着UDP在传输数据时,将数据分割成独立的数据报,每个数据报都具有完整的信息,包括源和目标端口号以及数据内容。这些数据报是独立的,没有连接状态或顺序关系,因此它们可以以无特定顺序传输,也可以在接收端以不同的顺序到达。UDP不维护连接状态,也不提供流量控制、拥塞控制或数据包重传机制,这使其成为一种轻量级的协议,适合那些对传输速度更加敏感而能够容忍一些数据包丢失的应用场景。
而TCP协议是一种面向字节流的协议。在TCP通信中,数据被视为一连串的字节,而不是独立的数据报(如UDP)。TCP协议负责将这些字节从发送方传递到接收方,并在传输过程中确保数据的可靠性、完整性和顺序性。因为TCP维护连接状态,并在通信双方之间建立虚拟的数据流,发送方将数据按字节流的方式发送,而接收方在接收数据时会按照相同的顺序重新组装这些字节。TCP还提供流量控制和拥塞控制机制,以确保网络上的数据传输不会导致过度拥塞或丢失。TCP协议用于需要保证数据可靠传输、保持数据顺序的应用场景,如文件传输、Web浏览、电子邮件等。
总的来说,UDP(用户数据报协议)和TCP(传输控制协议)都是传输层协议,用于控制网络数据的传输。它们在不同的应用场景和需求下各有优劣。不同应用根据其数据传输的要求和特性,应当选择适当的协议。
网络字节序
我们都知道在内存中的多字节数据相对于内存地址有大端和小端之分,,而磁盘文件中的多字节数据相对于文件中的偏移地址也存在大端小端之分,在网络数据流也同样有大端小端之分。因为不同的主机的大小端如果不同,那么发送出去的数据被不同的主机读取,数据读取的顺序也就不同。因此,为了更好的进行管理,网络数据流的地址应这样规定,先发出的数据是低地址,在发出后要转换为高地址。在TCP/IP协议中就是这样规定,网络数据流应采用大端字节序,即最高有效字节存储在最低地址,而最低有效字节存储在最高地址。这与大多数网络协议和标准兼容,因此成为了网络数据传输的通用规范。
在编程中,为了确保数据在网络上正确传输,通常需要使用网络字节序来编码和解码数据。编程语言和库通常提供了函数或方法来执行这些操作,如htonl(Host to Network Long)、htons(Host to Network Short)、ntohl(Network to Host Long)和ntohs(Network to Host Short)等。这几个函数原型如下:
htonl 函数是一个用于将本机字节顺序的 32 位整数(Host Order)转换为网络字节顺序的 32 位整数(Network Order)的函数。其中 hostlong 是要进行转换的本机字节顺序的 32 位整数,而 htonl 返回其对应的网络字节顺序的 32 位整数。htons 函数与 htonl 函数类似,是一个用于将本机字节顺序的 16 位整数(Host Order)转换为网络字节顺序的 16 位整数(Network Order)的函数。
ntohl 和 ntohs 函数是用于将网络字节顺序的整数转换为本机字节顺序的整数的函数,与之前提到的 htonl 和 htons 相反。它们在网络编程中用于解析从网络接收到的数据,以确保正确地处理来自不同计算机和操作系统的数据。ntohl 是 Network to Host Long 的缩写,用于将网络字节顺序的 32 位整数转换为本机字节顺序的 32 位整数并返回。ntohs 是 Network to Host Short 的缩写,用于将网络字节顺序的 16 位整数转换为本机字节顺序的 16 位整数。总之,网络字节序是确保数据在不同计算机和操作系统之间正确传输和解释的重要规则。
总结
文章介绍了Linux网络编程中一些相关的基础概念,为进行网络编程铺路,如果你也想学习Linux网络编程的话,关注博主,订阅专栏,我们一起学习,一起进步吧!码文不易,如果文章对你有帮助的话,就给博主点一个👍呗,谢谢支持!