Linux socket编程(1):套接字、字节序和地址结构体

news/2024/12/29 16:44:17/

套接字(socket)是一种使用标准Unix文件描述符与其他程序进行通信的方式,它在实际的应用中都十分常用。所以从这一篇文章开始,我将详细介绍一下Linux环境下的socket的用法。本篇文章将介绍套接字、字节序和地址结构体的相关知识。

文章目录

  • 1 什么是套接字
  • 2 字节序
  • 3 地址结构体

1 什么是套接字

计算机网络由多个层组成,每个网络层提供关于该层数据的不同限制。而套接字的本意是提供一种进程间通信的方法,使得在相同或不同主机上的进程能够以相同的规范进行双向的信息传送。如下图所示,套接字接口提供了对网络下层(1-4层)的统一API,并能套接字应用程序中实现上层(5-7层和应用格式)功能。
在这里插入图片描述

套接字是一种通用的编程接口,可以用于与不同类型的网络协议进行交互,不仅仅限于IP协议,还有UDP、ICMP等。在实际应用中,套接字应用程序通常会依赖于IP协议来实现网络通信。在传输层,套接字支持两种特定的协议:TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)。其中,TCP是面向连接、可靠、有序的流协议,而UDP是无连接、不可靠、自我界定的数据报协议。

在Linux中,Layer2-Layer4已经由内核实现,所以套接字可以看做是内核提供的给用户使用的网络协议栈的编程接口。

在这里插入图片描述

2 字节序

端口号和IP地址由多字节数据类型表示,它们被放置在数据包中,用于路由和多路复用。端口号占据2个字节,IPv4地址占据4个字节,但在不同架构之间传输多字节数据类型时会出现问题。

大端(Big-Endian)和小端(Little-Endian)是两种不同的字节序方式,用于表示多字节数据类型(如整数、浮点数)在计算机内存中的存储方式。

  • 大端字节序:MSB(最高有效位)位于地址最低的内存单元
  • 大端字节序:LSB(最低有效位)位于地址最低的内存单元

如下图所示,一个64位的值0x1122334455667788,在小端机器的内存中为0x8877665544332211,而在大端机器的内存中为0x1122334455667788。

在这里插入图片描述

如下图所示,可以通过程序来判断计算机的字节序:
在这里插入图片描述

在网络协议中,使用的是大端字节序,而大部分的主机使用的是小端字节序。所以,在Socket编程中提供了下面的函数来更改IP和端口号的字节序:

1.转换端口号(16位的整数)
Host->Network:主机字节序转网络字节序
unit16_t htons(uint16_t hostportnumber)
Network->Host:网络字节序转主机字节序
unit16_t ntohs(uint16_t netportnumber)2.转换IPV4地址(32位的整数)
Host->Network
unit32_t htonl(uint32_t hostportnumber)
Network->Host
Unit32_t ntohl(uint32_t netportnumber)

3 地址结构体

connect()accept()bind()等套接字函数需要使用明确定义的地址结构来保存IP地址信息、端口号和协议类型。我们使用套接字来编写使用不同协议的网络应用程序,比如我们可以使用IPV4、IPV6、Unix等。问题在于:每种不同的协议都使用不同的地址结构来保存其寻址信息。

我们有存在一个通用的地址结构:struct sockaddr,在传递给这些套接字函数时,必须将您特定于协议的地址结构强制转换为通用的地址结构。

特定于协议的地址结构通常以sockaddr_开头,并以取决于该协议的后缀结尾。如下:

  1. struct sockaddr_in:
    • sockaddr_in 结构用于表示IPv4地址,通常称为"Internet地址"。它包含 IP 地址、端口号和协议族信息。这是在IPv4网络编程中最常使用的结构。
  2. struct sockaddr_in6:
    • sockaddr_in6 结构用于表示IPv6地址,与 sockaddr_in 类似,但适用于IPv6网络编程。它包含IPv6地址、端口号和协议族信息。
  3. struct sockaddr_un:
    • sockaddr_un 结构用于表示本地Unix套接字地址。Unix域套接字是用于本地通信的一种方式,而不是通过网络进行通信。它包含套接字文件的路径信息。
  4. struct sockaddr_dl:
    • sockaddr_dl 结构用于表示数据链路层地址,通常在底层网络编程中使用。这包括硬件地址,如MAC地址。这通常用于需要直接访问底层网络的应用程序。

本篇文章仅介绍IP4地址结构:struct sockaddr_in,来看一下它的结构体成员:

struct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */in_port_t      sin_port;   /* port in network byte order */struct in_addr sin_addr;   /* internet address */
};/* Internet address */
struct in_addr {uint32_t       s_addr;     /* address in network byte order */
};
  • sin_family:地址结构的类型,在这里固定设置为 AF_INET,表示这是一个IPv4地址结构
  • sin_port:端口号
  • struct in_addr sin_addr:IPv4地址信息的结构体,该结构体中使用s_addr存储32位的IPv4地址

我们平时使用的地址都是192.168.1.1这种类型的,如果要转换为s_addr类型的整数,我们可以使用inet_addrinet_aton将点分十进制字符串表示的IPv4地址转换为网络字节顺序的32位整数。

  • inet_addr已经过时了,建议使用inet_aton ,因为它可以提供更多的错误处理信息

反过来,我们可以使用inet_ntoa()将32位的网络字节顺序的整数表示的IPv4地址转换为点分十进制字符串。

在这里插入图片描述


http://www.ppmy.cn/news/1213637.html

相关文章

Jenkins简介及Docker Compose部署

Jenkins是一个开源的自动化服务器,用于自动化构建、测试和部署软件项目。它提供了丰富的插件生态系统,支持各种编程语言和工具,使得软件开发流程更加高效和可靠。在本文中,我们将介绍Jenkins的基本概念,并展示如何使用…

【Java】定时任务 - Timer/TimerTask 源码原理解析

一、背景及使用 日常实现各种服务端系统时,我们一定会有一些定时任务的需求。比如会议提前半小时自动提醒,异步任务定时/周期执行等。那么如何去实现这样的一个定时任务系统呢? Java JDK提供的Timer类就是一个很好的工具,通过简单…

Spring Cloud学习(六)【统一网关 Gateway】

文章目录 网关的功能搭建网关服务路由断言工厂Route Predicate Factory路由过滤器 GatewayFilter过滤器执行顺序跨域问题处理 网关的功能 网关功能: 身份认证和权限校验服务路由、负载均衡请求限流 在SpringCloud中网关的实现包括两种: gatewayzuul …

Spark Job优化

1 Map端优化 1.1 Map端聚合 map-side预聚合,就是在每个节点本地对相同的key进行一次聚合操作,类似于MapReduce中的本地combiner。map-side预聚合之后,每个节点本地就只会有一条相同的key,因为多条相同的key都被聚合起来了。其他节…

Linux 之 MakeFile

MakeFile 前言MakeFile基本介绍MakeFile介绍MakeFile文件命名Makefile编写规则MakeFile的执行步骤 MakeFilemakefile组成元素makefile显示规则makefile隐晦规则伪目标(标签与文件冲突问题) makefile变量定义makefile中的运算符和特殊变量 makefile文件指示makefile注释 makefil…

深入理解指针(一)

目录 内存和地址 内存 如何理解编址 指针变量和地址 取地址操作符(&) 指针变量和解引用操作符(*) 指针变量 如何拆解指针类型 解引用操作符 指针变量的大小 ​编辑 指针变量类型的意义 指针的解引用 指针-整…

python异常、模块与包

1.异常 异常:当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的BUG。 1.1捕获异常 基本语法: try:可能发生错误代码 except:如果出现…

jsp小知识

jsp小知识 1[单选题] 用户登录功能中,用到的数据库操作是( )。 正确答案: C 我的答案: C A. 增加 B. 删除 C. 查询 D. 修改 2[单选题] 下列说法错误的是( )。 正确答案: C 我的答案: C A. JDBC API包括一组支…