计算机网络套接字知识(非常详细)从零基础入门到精通

本节重点

  • 认识IP地址, 端口号, 网络字节序等网络编程中的基本概念;

  • 学习socket api的基本用法;

一、预备知识

1.理解源IP地址和目的IP地址

⭐在IP数据包头部中,有两个IP地址,分别叫做源IP地址和目的IP地址。

思考: 我们光有IP地址就可以完成通信了嘛?想象一下发qq消息的例子,有了IP地址能够把消息发送到对方的机器上,但是还需要有一个其他的标识来区分出,这个数据要给哪个程序进行解析,此时就需要我们的目的IP地址。

2.认识端口号

在进行网络通信的时候,是不是我们的两台机器在进行通信呢?本质是应用层在通信

几乎任何层的协议,都要在报头中提供,决定将自己的有效载荷交付给上层的哪一个协议的能力,怎么做到的呢?端口号(port)是传输层协议的内容.

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用.

3.理解 "端口号" 和 "进程ID"

我们之前在学习系统编程的时候,学习了 pid 表示唯一一个进程;此处我们的端口号也是唯一表示一个进程,那么这两者之间是怎样的关系?

另外,一个进程可以绑定多个端口号;但是一个端口号不能被多个进程绑定。

4.理解源端口号和目的端口号

传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 就是在描述 "数据是谁发的, 要发给谁"。

socket通信本质上就是两个进程之间在进行通信,只不过这里是跨网络的进程间通信。比如看QQ和刷抖音的动作,实际就是手机上的QQ进程和抖音进程在和对端服务器主机上的QQ服务进程和抖音服务进程之间在进行通信。因此进程间通信的方式除了管道、消息队列、信号量、共享内存等方式外,还有套接字,只不过前者是不跨网络的,而后者是跨网络的。

⭐理解socket这个名字

socket在英文上有“插座”的意思,插座上有不同规格的插孔,我们将插头插入到对应的插孔当中就能够实现电流的传输。在进行网络通信时,客户端就相当于插头,服务端就相当于一个插座,但服务端上可能会有多个不同的服务进程(多个插孔),因此当我们在访问服务时需要指明服务进程的端口号(对应规格的插孔),才能享受对应服务进程的服务。

5.认识TCP协议和UDP协议

此处我们先对TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识; 后面我们再详细讨论TCP的一 些细节问题.

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

此处我们也是对UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识; 后面再详细讨论.

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

TCP协议是一种可靠的传输协议,使用TCP协议能够在一定程度上保证数据传输时的可靠性,而UDP协议是一种不可靠的传输协议,UDP协议的存在有什么意义?

首先,可靠是需要我们做更多的工作的,TCP协议虽然是一种可靠的传输协议,但这一定意味着TCP协议在底层需要做更多的工作,因此TCP协议底层的实现是比较复杂的,我们不能只看到TCP协议面向连接可靠这一个特点,我们也要能看到TCP协议对应的缺点。同样的,UDP协议虽然是一种不可靠的传输协议,但这一定意味着UDP协议在底层不需要做过多的工作,因此UDP协议底层的实现一定比TCP协议要简单,UDP协议虽然不可靠,但是它能够快速的将数据发送给对方,虽然在数据在传输的过程中可能会出错。

6.网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏 移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
  • 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序数将数据据;来发送/接收
  • 如果当前发送主机是小端, 就需要先转成大端; 否则就忽略, 直接发送即可;

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络 字节序和主机字节序的转换。

  • 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地

二、socket编程接口

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);

2.sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同.

为什么没有用void*代替struct sockaddr*类型?

我们可以将这些函数的struct sockaddr*参数类型改为void*,此时在函数内部也可以直接指定提取头部的16个比特位进行识别,最终也能够判断是需要进行网络通信还是本地通信,那为什么还要设计出sockaddr这样的结构呢?实际在设计这一套网络接口的时候C语言还不支持void*,于是就设计出了sockaddr这样的解决方案。并且在C语言支持了void*之后也没有将它改回来,因为这些接口是系统接口,系统接口是所有上层软件接口的基石,系统接口是不能轻易更改的,否则引发的后果是不可想的,这也就是为什么现在依旧保留sockaddr结构的原因。

  • Pv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16位端口号和32位IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • socket API可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;

⭐sockaddr 结构

sockaddr_in 结构

虽然socket api的接口是sockaddr, 但是我们真正在基于IPv4编程时, 使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息: 地址类型,端口号,IP地址,可是我们怎么没看到套接字的域呢?

这里使用了我们的"##",我们来回忆一下它的用法

所以上面定义的宏传入的参数是sin_,然后宏里面使用了"##"拼接family,这样就看到了我们的套接字的域。

⭐in_addr结构

可以看到,struct sockaddr_in当中的成员如下:

  • sin_family:表示协议家族。
  • sin_port:表示端口号,是一个16位的整数。
  • sin_addr:表示IP地址,是一个32位的整数。

in_addr用来表示一个IPv4的IP地址. 其实就是一个32位的整数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux Tcpdump抓包入门

Linux Tcpdump抓包入门 一、Tcpdump简介 tcpdump 是一个在Linux系统上用于网络分析和抓包的强大工具。它能够捕获网络数据包并提供详细的分析信息,有助于网络管理员和开发人员诊断网络问题和监控网络流量。 安装部署 # 在Debian/Ubuntu上安装 sudo apt-get install…

基于Perfetto 解读一帧的生产消费流程 Android >= S Qualcomm

广告 首先帮我朋友打个广告 我们一起在运营一个视频号 感兴趣的可以帮忙点击右边这个小铃铛 铃铛 序 1.这个流程里面的东西如果展开其实是有很多的 内容其实还是比较浅显的 sf处就不贴源码了 关一个Vsync就有的解释 当然笔者在流程上先形成一个思维闭环 2.如有小伙伴需要 笔…

C++完成特色旅游管理信息系统

背景: 继C完成淄博烧烤节管理系统后,我们来到了特色旅游管理信息系统的代码编写,历史链接点下方。 C完成淄博烧烤节管理系统_淄博烧烤总账管理系统的-CSDN博客 问题描述: 为了更好的管理各个服务小组,开发相应的管…

C# 拓展方法(涉及Linq)

拓展方法 定义一个扩展方法使用扩展方法例如再举个例子终极例子 注意事项与Linq 在C#中,扩展方法是一种特殊的静态方法,允许开发者向现有类型“添加”新的方法,而无需修改该类型的源代码或创建新的派生类型。这种机制提供了一种更为灵活的方式…

结构化开发方法(数据流图)

一、系统设计基本原理 二、系统总体结构设计 三、数据流图 数据流图

出口加工园区gis三维可视化系统全面整合了企业线上线下资源与服务

园区作为产业协同和经济推动的关键节点,承载着企业生产、物流和服务等多种功能,数字孪生三维可视化技术的出现,通过数字孪生和3D可视化的方式,对园区情况和运营实现实时监测和管理,提高了运营效率和协同性。 园区数字孪…

STM32 学习——1. STM32最小系统

这是一个最小系统的测试,LED灯会进行闪烁。选用PC13口,因为STM32F103C8T6 硬件开发板中,这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…

Css 提高 - 获取DOM元素

目录 1、根据选择器来获取DOM元素 2.、根据选择器来获取DOM元素伪数组 3、根据id获取一个元素 4、通过标签类型名获取所有该标签的元素 5、通过类名获取元素 目标:能查找/获取DOM对象 1、根据选择器来获取DOM元素 语法: document.querySelector(css选择…

一套MES系统源码,技术架构springboot + vue-element-plus-admin

一、系统概述 MES全称Manufacturing Execution System,即制造执行系统,它是一套面向生产车间的管理系统。MES系统可用于实现制造业自动化和数字化转型,它可以帮助车间管理人员监控、跟踪、记录和控制从原材料到成品的产品制造流程&#xff0…

掌握Python基本语法的终极指南【基本语法部分】

一、基本语法部分 1.简单数据类型 1.1字符串类型及操作 字符串访问: 1.索引访问 mystr"Hello world" #索引访问 print(mystr[0]) #H print(mystr[-1]) #d print(mystr[-7]) #o print(mystr[6]) #w 2.切片访问 [头下标:尾下标] &#x…

基于Java、SpringBoot和uniapp在线考试系统安卓APP和微信小程序

摘要 基于Java、SpringBoot和uniapp的在线考试系统安卓APP微信小程序是一种结合了现代Web开发技术和移动应用技术的解决方案,旨在为教育机构提供一个方便、高效和灵活的在线考试平台。该系统采用Java语言进行后端开发,使用SpringBoot框架简化企业级应用…

储能服务系统架构:实现能源可持续利用的科技之路

随着可再生能源的快速发展和能源系统的智能化需求增加,储能技术作为能源转型和可持续发展的关键支撑之一,备受各界关注。储能服务系统架构的设计和实现将对能源行业产生深远影响。本文将探讨储能服务系统架构的重要性和关键组成部分,旨在为相…

【C++高阶(一)】继承

目录 一、继承的概念 1.继承的基本概念 2.继承的定义和语法 3.继承基类成员访问方式的变化 ​编辑 4.总结 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 1.派生类中的默认构造函数 2.派生类中的拷贝构造函数 3.派生类中的移动构造函数…

二维轮廓自动添加屋顶

1、背景介绍 在提取建筑物轮廓点后,对轮廓点进行简化得到建筑物轮廓线。将轮廓线进行拉伸,变可得到建筑物白膜,如下图所示。这种形状比较简单,所重建模型实质上就是一个个立方体盒子,缺少屋顶细节,视觉观感…

玩转盲盒潮流:从0到1搭建小程序平台

在当前的消费市场中,盲盒已成为一种炙手可热的消费模式,凭借其神秘性和随机性,迅速俘获了年轻消费者的心。作为一位有志于创新并紧跟市场趋势的创业者,你可能会想:如何从0到1搭建一个属于自己的盲盒小程序平台&#xf…

SpringBoot高级原理详解

文章目录 1 SpringBoot自动化配置原理01-SpringBoot2高级-starter依赖管理机制02-SpringBoot2高级-自动化配置初体验03-SpringBoot2高级-底层原理-Configuration配置注解04-SpringBoot2高级-底层原理-Import注解使用105-SpringBoot2高级-底层原理-Import注解使用206-SpringBoot…

linux---线程控制

线程和进程 以前我们要同时跑多个程序,可以通过fork()多个子进程,然后通过系统函数进行程序的替换,但是创建进程代价大,不仅要拷贝一份父进程的地址空间,页表,文件表述符表等。但是线程不需要因为是进程的…

frp搭建内网流量转发

前提条件 有一台外网服务器 背景介绍 外网服务器linux内网客户端Windows 10下载frp软件安装包 下载地址:https://github.com/fatedier/frp/releases 服务端软件包下载 客户端软件包下载 服务端部署 解压软件包 tar xzvf frp_0.58.0_linux_amd64.tar.gz修复加压后文件夹名…

TemperMonkey在百度搜索页面,提供跳转其他平台搜索、与批量打开搜索结果的功能的脚本代码

代码 // UserScript // name 百度搜索。链接其他搜索。跳转功能。 // namespace http://tampermonkey.net/ // version 0.1(2020-6-24 17:37:27) // description try to take over the world! // author gwd // match https://www.baidu.com/s?…

深度学习中的优化算法一(Pytorch 18)

一 优化和深度学习 优化算法 使我们能够 继续更新模型参数, 并使损失函数的值最小化。这就像在训练集上评估一样。事实上,任何满足于将优化视为黑盒装置,以在简 单的设置中最小化目标函数的人,都可能会知道存在着一系列此类“咒…