socket以及字节序

1. socket 介绍:

简介:

所谓 socket( 套接字),就是对网络中不同主机上的应用进程之间进行双向通信的 端点的抽象
一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处
的地位来讲,套接字 上联应用进程,下联 网络协议栈,是应用程序通过网络协议进行 通信的接口
是应用程序与网络协议根进行 交互的接口
socket 可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概
念。它是网络环境中进程间通信的 API,也是可以被命名和寻址的通信端点,使用中的每一个套接
字都有其类型和一个与之相连进程。 通信时其中一个网络应用程序将要传输的一段信息写入它所在
主机的 socket 中,该 socket 通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台
主机的 socket 中,使对方能够接收到这段信息。socket 是由 IP 地址和端口结合的,提供向应用
层进程传送数据包的机制。
socket 本身有“插座”的意思,在 Linux 环境下,用于表示进程间网络通信的 特殊文件类型。本质为
内核借助缓冲区形成的伪文件。既然是文件,那么理所当然的,我们可以 使用文件描述符引用套接
。与管道类似的,Linux 系统将其 封装成文件的目的是为了统一接口,使得读写套接字和读写文
件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传
递。

A将数据先写入写缓冲区,然后封装后发送到B,B分用(解封装)后数据被放入套接字的读缓冲区。
// 套接字通信分两部分:
- 服务器端:被动接受连接,一般不会主动发起连接
- 客户端:主动向服务器发起连接socket是一套通信的接口,Linux 和 Windows 都有,但是有一些细微的差别。

2. 字节序:

简介:

现代 CPU 的累加器一次都能装载(至少) 4 字节(这里考虑 32 位机),即一个整数。那么这 4
字节 在内存中排列的顺序将影响它被累加器装载成的整数的值,这就是字节序问题。在各种计算机
体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问
题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。
果不达成一致的规则,通信双方将无法进行正确的编码/译码从而导致通信失败。
字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数
据当然就无需谈顺序的问题了)
字节序分为大端字节序(Big-Endian) 和小端字节序(Little-Endian)。 大端字节序是指一个整
数的 最高位字节(23 ~ 31 bit)存储在内存的低地址处低位字节(0 ~ 7 bit)存储在内存的高地
址处;小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地
址处。

字节序举例:

上图0x11是最高位,所以放在高地址处(内存地址增长方向)。

上图0x12是最高位,所以放在低地址处。

判断本地主机是大端序还是小端序代码:

/*  字节序:字节在内存中存储的顺序。小端字节序:数据的高位字节存储在内存的高位地址,低位字节存储在内存的低位地址大端字节序:数据的低位字节存储在内存的高位地址,高位字节存储在内存的低位地址
*/// 通过代码检测当前主机的字节序
#include <stdio.h>int main() {union {short value;    // 2字节char bytes[sizeof(short)];  // char[2]} test;test.value = 0x0102;if((test.bytes[0] == 1) && (test.bytes[1] == 2)) {printf("大端字节序\n");} else if((test.bytes[0] == 2) && (test.bytes[1] == 1)) {printf("小端字节序\n");} else {printf("未知\n");}return 0;
}

字节序转换函数

当格式化的数据在两台使用不同字节序的主机之间直接传递时,接收端必然错误的解释之。解决问题的方法是:发送端总是把要发送的数据转换成大端字节序数据后再发送,而接收端知道对方传送过来的数据总是采用大端字节序,所以接收端可以根据自身采用的字节序决定是否对接收到的数据进行转换(小端机转换,大端机不转换)。
网络字节顺序 TCP/IP 中规定好的一种数据表示格式,它与具体的 CPU 类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释,网络字节顺序采用大端排序方式
BSD Socket 提供了封装好的转换接口,方 便程序员使用。包括从主机字节序到网络字节序的转换函数:htons、 htonl 从网络字节序到主机字节序的转换函数: ntohs ntohl
h - host 主机,主机字节序
to - 转换成什么
n - network 网络字节序
s - short unsigned short
l - long unsigned int
#include <arpa/inet.h>
// 转换端口
uint16_t htons(uint16_t hostshort); // 主机字节序 - 网络字节序
uint16_t ntohs(uint16_t netshort); // 网络字节序 - 主机字节序
// 转IP
uint32_t htonl(uint32_t hostlong); // 主机字节序 - 网络字节序
uint32_t ntohl(uint32_t netlong); // 网络字节序 - 主机字节序

测试代码如下:

/*网络通信时,需要将主机字节序转换成网络字节序(大端),另外一段获取到数据以后根据情况将网络字节序转换成主机字节序。// 转换端口uint16_t htons(uint16_t hostshort); // 主机字节序 - 网络字节序uint16_t ntohs(uint16_t netshort); // 网络字节序 - 主机字节序// 转IPuint32_t htonl(uint32_t hostlong); // 主机字节序 - 网络字节序uint32_t ntohl(uint32_t netlong); // 网络字节序 - 主机字节序
*/#include <stdio.h>
#include <arpa/inet.h>int main() {// htons 转换端口unsigned short a = 0x0102;printf("a : %x\n", a);unsigned short b = htons(a);printf("b : %x\n", b);printf("=======================\n");// htonl  转换IPchar buf[4] = {192, 168, 1, 100};int num = *(int *)buf;// 强转成int *,是4个字节,buf一共4个字节int sum = htonl(num);unsigned char *p = (char *)&sum;printf("%d %d %d %d\n", *p, *(p+1), *(p+2), *(p+3));printf("=======================\n");// ntohlunsigned char buf1[4] = {1, 1, 168, 192};int num1 = *(int *)buf1;int sum1 = ntohl(num1);unsigned char *p1 = (unsigned char *)&sum1;printf("%d %d %d %d\n", *p1, *(p1+1), *(p1+2), *(p1+3));// ntohsreturn 0;
}

输出结果为:

再来看一下a和b的输出疑问: 

gpt的解答:

你的理解基本正确,我会进一步解释一下。

在计算机中,整数在内存中以二进制形式存储,而不同的字节序会影响在内存中的表示方式。对于小端序(Little Endian)机器,最低有效字节存储在最低内存地址,而对于大端序(Big Endian)机器,最高有效字节存储在最低内存地址。

当你使用 `%x` 格式化输出时,实际上是将内存中的二进制数据格式化为十六进制字符串,这并不会改变数据在内存中的存储方式。因此,`a` 在小端序机器上在内存中的表示是 `02 01`,但是在使用 `%x` 输出时,它被格式化为 `0x0102`,这只是一种表示形式。

同样,`htons` 和 `htonl` 等函数并不改变内存中的实际存储方式,它们只是负责在不同字节序之间进行转换。这些函数的目的是确保在网络通信中数据的一致性,而不是改变内存中的存储方式。

所以,你的理解是正确的:输出的值是通过格式化方式呈现的,而不是真正改变了内存中的存储方式。

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

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

相关文章

Vulnhub靶机:FunBox 5

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;FunBox 5&#xff08;10.0.2.30&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/funb…

C# 将HTML网页、HTML字符串转换为PDF文件

将HTML转换为PDF可实现格式保留、可靠打印、文档归档等多种用途&#xff0c;满足不同领域和情境下的需求。本文将通过以下两个示例&#xff0c;演示如何使用第三方库Spire.PDF for .NET和QT插件在C# 中将Html 网页&#xff08;URL&#xff09;或HTML字符串转为PDF文件。 HTML转…

引领AI变革:边缘计算与自然语言处理结合的无尽可能

引言 讲到Ai&#xff0c;你第一时间会想到什么&#xff1f;是Chagpt和文心一言这样与人类交流自然的Ai生成式对话服务&#xff1f;还是根据关键字快速制图的Ai绘图&#xff1f;这些都是近年来人们所常知的Ai用途&#xff0c;我们今天来讲讲以自然语言处理为辅&#xff0c;在Ai赋…

在 Python 中使用 OpenCV 通过透视校正转换图像

在计算机视觉和图像处理领域&#xff0c;透视变换是一个强大的工具。它允许我们改变图像的视角以获得新的视点&#xff0c;通常用于校正扭曲或模拟不同的相机角度。本文将探讨一个 Python 脚本&#xff0c;该脚本使用计算机视觉领域流行的 OpenCV 库对图像执行透视变换。我们将…

01-TiDB概述

分布式关系型数据库 1、支持在线事务处理与在线分析处理 (Hybrid Transactional and Analytical Processing, HTAP) &#xff1a;OLTP (Online Transactional Processing)、OLAP (Online Analytical Processing)解决方案 2、无限制的水平扩容或者缩容 3、兼容MySQL &#xf…

openresty 安装, nginx与 openresty

openresty VS nginx Nginx 是一款高性能的 Web 服务器和反向代理服务器&#xff0c;具备基础的功能如HTTP服务、负载均衡、反向代理以及动静分离等。它是许多互联网应用的核心组件&#xff0c;因其模块化和可扩展的设计而受到欢迎。1 OpenResty 是基于 Nginx 的 Web 平台&…

nodeJs+express+Vue+MongoDB

数据库【Sqlite3、MongoDB、Mysql】简介&小记 Sqlite3&#xff1a; SQLite3是一个轻量级的数据库系统&#xff0c;它被设计成嵌入式数据库。这意味着它是一个包含在应用程序中的数据库&#xff0c;而不是独立运行的系统服务。适用场景&#xff1a;如小型工具、游戏、本地…

ubuntu20根目录扩容

ubuntu根目录/ 或者 /home文件夹有时出现空间满了的情况&#xff0c;可以用gparted工具进行空间的重新分配。 首先&#xff0c;如果你是双系统&#xff0c;需要从windows系统下磁盘压缩分配一部分未使用的空间给ubuntu&#xff0c;注意压缩的空间要邻接ubuntu所在盘的位置。 …

力扣刷MySQL-第七弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

【Flink-1.17-教程】-【五】Flink 中的时间和窗口(2)时间语义

【Flink-1.17-教程】-【五】Flink 中的时间和窗口&#xff08;2&#xff09;时间语义 1&#xff09;Flink 中的时间语义2&#xff09;时间语义的分类2.1.处理时间&#xff08;process time&#xff09;2.2.摄取时间&#xff08;ingestion time&#xff09;2.3.事件时间&#xf…

大创项目推荐 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

Webpack5 基本使用 - 3(完结)

环境区分 可以定义多个配置文件&#xff0c;通过 webpack-merge 合并配置文件。 安装 webpack-merge yarn add webpack-merge公共配置 // webpack.common.js const path require(path) const HtmlWebpackPlugin require(html-webpack-plugin)module.exports {entry: path…

外呼机器人有什么优势?

外呼机器人有什么优势&#xff1f;值得受到大多数电销企业的追捧&#xff01; 1、电话外呼效率高&#xff1a; 每天可拨打的电话数量是人工的5-10倍&#xff0c;人工一天只能拨打200-300通电话&#xff0c;机器人每天能打3000通电话以上&#xff0c;无须休息&#xff0c;按照…

Java-NIO篇章(4)——Reactor反应器模式

前面已经讲过了Java-NIO中的三大核心组件Selector、Channel、Buffer&#xff0c;现在组件我们回了&#xff0c;但是如何实现一个超级高并发的socket网络通信程序呢&#xff1f;假设&#xff0c;我们只有一台内存为32G的Intel-i710八核的机器&#xff0c;如何实现同时2万个客户端…

openGauss学习笔记-206 openGauss 数据库运维-常见故障定位案例-too many clients already

文章目录 openGauss学习笔记-206 openGauss 数据库运维-常见故障定位案例-too many clients already206.1 高并发报错“too many clients already”或无法创建线程206.1.1 问题现象206.1.2 原因分析206.1.3 处理办法 openGauss学习笔记-206 openGauss 数据库运维-常见故障定位案…

143基于matlab的2D平面桁架有限元分析

基于matlab的2D平面桁架有限元分析&#xff0c;可以改变材料参数&#xff0c;输出平面结构外形&#xff0c;各桁架应力&#xff0c;位移及作用力。可查看节点力&#xff0c;程序已调通&#xff0c;可直接运行。 143 matlab 平面桁架 有限元分析 桁架应力 (xiaohongshu.com)

element-ui 树形控件 通过点击某个节点,遍历获取上级的所有父节点和本身节点

1、需求&#xff1a;点击树形控件的某个节点&#xff0c;需要拿到它上级的所有父节点进行操作 2、代码&#xff1a; 树形控件代码 <el-tree:data"deptOptions"node-click"getVisitCheckedNodes"ref"target_tree_Speech"node-key"id&qu…

prometheus监控RabbitMQ策略

一般用官方的rabbitmq_exporter采取数据即可&#xff0c;然后在普米配置。但如果rabbitmq节点的队列数超过了5000&#xff0c;往往rabbitmq_exporter就会瘫痪&#xff0c;因为rabbitmq_exporter采集的信息太多&#xff0c;尤其是那些队列的细节&#xff0c;所以队列多了&#x…

ubuntu下docker卸载和重新安装

卸载&#xff1a;步骤一&#xff1a;停止Docker服务 首先&#xff0c;我们需要停止正在运行的Docker服务。打开终端&#xff0c;执行以下命令&#xff1a; sudo systemctl stop docker 步骤二&#xff1a;删除Docker安装包 接下来&#xff0c;我们需要删除已经安装的Docker软件…

2024年美赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…