【socket编程】预备知识 {IP地址和MAC地址;端口号;认识TCP/UDP协议;网络字节序;socket编程入门}

news2024/9/21 3:14:22

一、IP地址和MAC地址

源IP地址和目的IP地址

  • IP地址用于唯一标识网络中的一台主机
  • 在IP数据包头部中(网络层), 有两个IP地址, 分别叫做源IP地址, 和目的IP地址
  • 这两个地址在网络传输过程中是不变的,因为它们是数据包的一部分,并且用于确定数据包的源和目的地。
  • 源IP和目的IP的作用是:引导路由和转发,方便路径选择

源MAC地址和目的MAC地址

  • MAC地址用于标识局域网中主机的网络接口。
  • 源MAC地址和目的MAC地址是包含在链路层的报头当中的
  • 而MAC地址实际只在当前局域网内有效,出局域网后路由器会重新封装源和目标MAC。
  • 源MAC和目标MAC的作用是:在同一局域网内使用MAC地址确定目标主机的网络接口,直接传输数据。

总的来说,IP 地址用于标识主机在网络中的位置,MAC 地址用于标识局域网中主机的网络接口。在不同网络之间的通信,通常需要使用 IP 地址引导路由和转发;而在同一局域网内的通信,则需要使用 MAC地址进行直接传输。


二、端口号

端口号(port)是传输层协议的内容:(在OS内)

  • 端口号用于唯一的标识该主机上的一个网络应用层进程,通过端口号可以将网络数据分用给指定的进程。

  • 端口号是一个2字节16位的整数,范围0~65535;

  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程,标识进程在全网的唯一性

  • 所以网络通信的本质其实就是进程间通信

  • 一个端口号只能被一个进程占用,但一个进程可以绑定多个端口号。

  • 其中 0~1023 的端口号被保留用于一些特定的服务和应用程序,称为“系统端口”或“熟知端口”,例如 HTTP 服务使用的端口号为 80,SMTP 服务使用的端口号为 25。每个端口号都与一个特定的应用程序或服务相关联,用于区分同一主机上的不同应用程序。

进程PID就已经标识了同一台主机上进程的唯一性,为什么又设计了端口号?

  1. 模块解耦:单独设置端口号是为了使系统模块与网络模块解耦,方便后期的更新和维护。
  2. PID 是动态的:当一个应用程序在计算机上启动时,它被分配一个 PID。但是,当该应用程序终止后,该 PID 将被释放并可以被操作系统重新分配给其他进程。因此,使用 PID 来标识应用程序可能会导致标识符冲突或混淆。

客户端和服务端是如何知道对方的IP+端口号用于进行网络通信的?

  • 要保证客户端每次都能找到服务端的进程,就必须要保证服务端的 IP + port 的唯一性,固定性,公开性。因此服务端进程的IP+端口号不能随意改变,且必须公开给客户端。
  • 软件都是用户主动打开的,所以几乎大部分情况都是客户端先向服务端发起请求,事实上,一台主机发送数据给另一台主机,发送方除了要发送数据外还要把自己的 IP + 端口号发送给对方,服务端进程反转源和目标就可以将数据转发给客户端了。
  • 所以在未来发送数据的时候一定会多发一部分数据,多发的这部分数据以协议的形式呈现

操作系统如何根据端口号找到指定的进程?

  • 实际底层采用哈希映射的方式建立了端口号和进程PID之间的映射关系,当底层拿到端口号时就可以匹配到对应的进程了。

三、认识TCP/UDP协议

TCP协议

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

TCP协议是面向连接的,如果两台主机之间想要进行数据传输,那么必须要先建立连接,当连接建立成功后才能进行数据传输。

其次,TCP协议是保证可靠的协议,数据在传输过程中如果出现了丢包、乱序等情况,TCP协议都有对应的解决方法

UDP协议

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

使用UDP协议进行通信时无需建立连接,如果两台主机之间想要进行数据传输,那么直接将数据发送给对端主机就行了

但是UDP协议是不可靠的,数据在传输过程中如果出现了丢包、乱序等情况,UDP协议本身是不知道的,也无法处理

有了TCP可靠传输,为什么还要有UDP?

  • 这里的可靠和不可靠是中性词,没有褒贬之义。可靠伴随着成本的提高,实现更复杂,维护和编码成本更高;不可靠的实现成本低,实现比较简单,维护和使用成本低
  • UDP和TCP都是有适合自己的场景的,比如TCP就比较适合银行的交易系统等,UDP就比较适合直播或者投递广告,两者一般都是一起结合使用的:网络流畅、可靠性要求不高时就使用UDP协议进行数据传输,而当网速不好或可靠性要求高的场景就使用TCP协议进行数据传输。

四、网络字节序

计算机的存储是分大小端的,在C语言已经学习过了

  • 大端模式: 数据的高字节内容保存在内存的低地址处,数据的低字节内容保存在内存的高地址处。
  • 小端模式: 数据的高字节内容保存在内存的高地址处,数据的低字节内容保存在内存的低地址处。

在这里插入图片描述

内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分

如果只在一台主机上,那么是不需要考虑大小端问题的,因为同一台机器上的数据采用的存储方式都是一样的,要么采用的都是大端存储模式,要么采用的都是小端存储模式。

但如果涉及跨主机网络通信,那就必须考虑大小端的问题,否则其他主机识别出来的数据可能与发送端想要发送的数据是不一致的

比如,两台主机之间在进行网络通信,其中发送端是小端机,而接收端是大端机。发送端将发送缓冲区中的数据按内存地址从低到高的顺序发出后,接收端从网络中获取数据依次保存在接收缓冲区时,也是按内存地址从低到高的顺序保存的

但由于发送端和接收端采用的分别是小端存储和大端存储

发送端按小端的方式发送数据,比如:0x12345678,发送的顺序是:78 56 34 12,小端识别数据是正常的:0x12345678

而接收端是大端存储,接受数据的顺序是 78 56 34 12,最后识别的数据是:0x78563412

此时接收端识别到的数据与发送端原本想要发送的数据就不一样了,这就是由于大小端的偏差导致数据识别出现了错误

解决方法

  • 解决方法简单粗暴:规定网络中的数据都是大端
  • 即发送端是小端,需要先将数据转成大端,然后再发送到网络当中
  • 发送端是大端,则可以直接进行发送
  • 接收端是小端,需要先将接收的网络数据转成小端后再进行数据识别
  • 接收端是大端,则可以直接进行数据识别

总结

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出

  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存

  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址

  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高权值

  • 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据

  • 如果当前发送主机是小端,就需要先将数据转成大端;否则就忽略,直接发送即可

网络字节序与主机字节序之间的转换

为使网络程序具有可移植性,使同样的代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换
注:转换工作不需要我们自己做。直接调用库函数即可完成

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • 函数名当中的h表示 host,n表示 network,l表示 long,32位长整数,s表示 short,16位短整数

  • htonl的意思就是:把32位的主机字节序转换成(to)32位网络字节序

  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回

  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回


五、套接字编程

socket的中文意思是插座,在计算机叫套接字

在进行网络通信时,客户端就相当于插头,服务端就相当于一个插座,但服务端上可能会有多个不同的服务进程(多个插孔),因此当我们在访问服务时需要指明服务进程的端口号(对应规格的插孔),才能享受对应服务进程的服务

套接字的种类大致分三种:

  1. 网络套接字编程:应用于跨主机网络通信,也支持本地通信
  2. unix域间套接字:只能进行本地通信
  3. 原始套接字:可以从应用层直接绕开传输层,直接去访问底层协议,通常用于各种抓包软件、网络侦测工具

由于有三种套接字,为了使用方便,接口设计者就只设计了一套接口,可以通过传不同的参数,解决所有网络或者其他场景下的网络通信

注:后面只讲网络套接字,域间套接字的使用方法基本相同

5.1 socket常见API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
 
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,
socklen_t address_len);
 
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
 
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,
socklen_t* address_len);
 
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

5.2 sockaddr结构

前面说到设计者只设计了一套接口,这套接口里面最重要的就是sockaddr结构体,除此之外还有两个结构体:sockaddr_in和sockaddr_un

  • sockaddr_in结构体是用于跨网络通信,其中sockaddr_in的in是inet,“inet” 是Internet Protocol(IP)的简写

  • sockaddr_un结构体是用于本地通信,其中sockaddr_un的un是unix

但是我们使用函数时,传的参数是sockaddr结构体,并不是sockaddr_in和sockaddr_un

sockaddr结构体的前16位表示地址类型,函数会以传入对应的地址类型解释该结构。

我们需要做的就是对sockaddr_in和sockaddr_un结构体进行填充,然后传参给sockaddr,这个过程必须要强制类型转换

在socket函数的内部,对于传进来的参数sockaddr直接取前两个字节,进行判断是网络通信还是本地通信,知道这个结果后再强制类型转换回sockaddr_in和sockaddr_un结构体

用这样的设计方式,就可以设计出同一套套接字接口了。

在这里插入图片描述

为什么不用void*代替struct sockaddr*?

  • 因为当时设计这些socket接口时,C语言的语法还不支持void*。

  • 并且在C语言支持了void*之后也没有将它改回来,因为这些接口是系统接口,直接内嵌在OS里面的,系统接口是所有上层软件接口的基石,系统接口是不能轻易更改的,否则会带来某些严重的后果

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

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

相关文章

Serverless 1

一、云原生应用 云原生应用覆盖到&#xff1a; 大数据&#xff0c;人工智能&#xff0c;边缘计算&#xff0c;区块链等 服务代理&#xff1a;envoy API 网关&#xff1a;APISIX 服务网格&#xff1a;Istio 服务发现&#xff1a;CoreDNS 消息和流式处理&#xff1a;kafka Serve…

打造高效校园办公:智慧校园行政办公合同类型

智慧校园行政办公中的合同类型功能是为了满足校园内各种合同管理需求而设计的一套数字化管理系统。该功能旨在提高合同管理效率&#xff0c;简化合同处理流程&#xff0c;确保合同内容的准确性和合规性。 智慧校园行政办公中的合同类型功能支持多种类型的合同管理&#xff0c;包…

【书生大模型实战营第三期 | 基础岛第1关-书生大模型全链路开源体系】

学习心得&#xff1a;《书生浦语大模型全链路开源开放体系》 摘要 通过观看哔哩哔哩上的《书生浦语大模型全链路开源开放体系》视频&#xff0c;我对开源大模型及其工具链有了更深入的了解。视频由社区贡献者汪周谦讲解&#xff0c;不仅介绍了书生浦语大模型的架构和功能&…

Excel公式与函数(运算符,计算限制,错误检查)(一)

公式 公式概念 公式 是以“”号为引导&#xff0c;用过运算符按照一定的顺序组合进行数据运算处理的等式&#xff0c;函数 则是按特定算法执行计算的产生一个或一组结果的预定义的特殊公式。 公式组成要素 公式的组成要素为“”&#xff0c;运算符&#xff0c;单元格引用&a…

基于STM32F407+NBIOT+华为云IOT平台设计的环境检测系统

基于STM32F407NBIOT华为云IOT平台设计的环境检测系统实现的功能&#xff1a; 【1】能够采集本地环境的温度、湿度、烟雾浓度&#xff0c;火光信息&#xff0c;在OLED显示屏上显示。 如果检测到烟雾、温度、火光超过阀值会触发蜂鸣器报警。 【2】能够通过NBIOT将本地设备采集的信…

LE-50821F/FA激光扫描传感器|360°避障雷达之性能参数与配置清单说明

LE系列激光扫描传感器|360避障雷达涵盖LE-50711、LE-50711F、​ LE-50621、LE-50821F、​LE-50621F、LE-50821FA、LE-50711FA、LE-50621FA等型号&#xff0c;广泛应用于自动化工厂、物流与仓储、汽车制造与物流、机械设备、能源与环境等领域的环境感知、高精度定位&#xff08;…

【dockerpython】亲测有效!适合新手!docker创建conda镜像+容器使用(挂载、端口映射、gpu使用)+云镜像仓库教程

文章目录 docker基本概念简介配置镜像加速源创建conda镜像1. 写 Dockerfile文件2. 创建镜像3. 创建容器并测试 容器的使用1. wsl挂载2. 端口映射3. 补充-gpu 云镜像仓库使用1. 登录2. 将本地镜像上传至云镜像仓库3. 从云镜像仓库下载镜像到本地 docker基本概念简介 简单来讲&a…

2024年“华数杯”数学竞赛A题完整解析 | 代码分享

机器臂关节角路径的优化设计 问题一 代码 Matlab clc clear % 参数定义 a [0, 300, 1200, 300, 0, 0]; alpha [0, -90, 0, -90, -90, -90]; d [600, 0, 0, 1200, 0, 0]; theta_min [-160, -150, -200, -180, -120, -180]; theta_max [160, 15, 80, 180, 120, 180]; P_t…

计算机网络(网络层)

网络层概述 网络层是干什么的&#xff1f; 网络层的主要任务是实现不同异构网络互连&#xff0c;进而实现数据包在各网络之间的传输相比于数据链路层的以太网通信&#xff0c;网络层则是将一个个数据链路层连接的以太网通过路由器连接起来。从而实现不同数据链路层的互联。 这…

【Linux】网络基础_3

文章目录 十、网络基础5. socket编程socket 常见APIsockaddr结构简单的UDP网络程序 未完待续 十、网络基础 5. socket编程 socket 常见API // 创建 socket 文件描述符 (TCP/UDP, 客户端 服务器) int socket(int domain, int type, int protocol);// 绑定端口号 (TCP/UDP, 服…

Ubuntu窗口如何自适应VM虚拟机

修改VM的显示设置 1&#xff1a;右击ubuntu计算机&#xff0c;点击设置按钮&#xff0c;进入到设置界面。 2&#xff1a;点击拉伸模式&#xff0c;选择自由拉伸。 以上操作结束之后打开ubuntu虚拟机。 ubuntu屏幕显示设置 进入到ubuntu系统之后&#xff0c;在桌面右击&…

网关与auth微服务缓存打通

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.缓存一致性问题1、更新了数据库&#xff0c;再更新缓存2、更…

大数据-68 Kafka 高级特性 物理存储 日志存储概述

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

文献翻译软件哪个好?6个工具让你轻松看懂外语文献

在医学研究领域&#xff0c;文献翻译软件扮演着至关重要的角色。 医学论文、研究报告和临床指南等&#xff0c;往往包含了大量的专业术语和复杂的句子结构&#xff0c;对于非母语者来说&#xff0c;理解这些内容无疑是一项挑战。 幸运的是&#xff0c;随着技术的发展&#xf…

巴黎奥运会8K转播科技为国产品牌自主研发设计

这个夏天&#xff0c;顶流是属于巴黎奥运会中国队的。 20枚金牌、15枚银牌、12枚铜牌......这个数字正随着赛事推进而不停在增加。赛场之上&#xff0c;中国健儿奋力拼搏、捷报频传&#xff0c;令人热血沸腾&#xff1b;赛场之外&#xff0c;另一支来自中国企业的“奥运选手”…

Linux OS:基于阻塞队列的生产者消费者模型

Linux OS&#xff1a;基于阻塞队列的生产者消费者模型 前言一、阻塞队列的大致框架二、生产者向阻塞队列中生产数据三、消费者获取阻塞队列中数据四、总体生产和消费思路及测试代码4.1 单生产单消费4.2 多生产多消费 五、所以代码 前言 阻塞队列是一种常用于实现生产者消费者模…

大模型微调技术PEFT

1. 横向对比 总体概览&#xff1a; 方法Transformer 中如何应用特点Prompt Tuning在输入到Transformer的input文本中添加Prompthard 模式prompt CO-STARP-tuning在输入到Transformer的embedding 层添加Promptsoft 模式 promptAdapter Tuning在 Transformer 中间层插入 Adapt…

MATLAB代码|蚁群算法|计算二元函数最大值

总述 蚁群方法求解二元函数的最大值。蚂蚁群先随机分布在定义域内&#xff0c;如下&#xff1a; 计算结束后&#xff0c;得到如下的分布&#xff0c;再计算分布均值&#xff0c;得到此时的自变量取值&#xff0c;因为是二元函数&#xff0c;所以有两个自变量&#xff0c;带入…

Qt 实战(9)窗体 | 9.1、QWidget

文章目录 一、QWidget1、定义与概念2、继承体系3、常用特性3.1、事件处理3.2、布局管理3.3、子控件与父子关系3.4、右键菜单 4、注意事项5、总结 前言&#xff1a; 在Qt这一强大的跨平台C图形用户界面应用程序开发框架中&#xff0c;QWidget扮演着至关重要的角色。作为所有用户…

【日记】为啥家族原发性高血压的人还喜欢喝酒啊……(442 字)

正文 今天跟人吵了一下午架&#xff0c;因为有一张报表换了新表&#xff0c;所有人都不知道怎么报。上级行一个想法&#xff0c;我一个想法。吵完都发现对方说得有道理&#xff0c;于是决定明天问省分行。难绷。草台班子。 鱼儿说他最近喜欢上了喝酒。我们劝他的同时&#xff0…