计算机网络(二) —— 网络编程套接字
目录
一,认识端口号
1.1 背景
1.2 端口号是什么
1.3 三个问题
二,认识Tcp协议和Udp协议
三,网络字节序
四,socket编程接口
4.1 socket常见API
4.2 sockaddr结构
一,认识端口号
1.1 背景
问题:在进行网络通信的时候,是不是我们的的两台机器在通信呢?
解答:我们把软件下载下来安装好,但是不打开,不耗费流量;只有当我们打开,它加载的时候才会耗流量。所以,网络通信的时候,本质是应用层在通信
- 网络协议的下三层:网络层,传输层,数据链路层,主要解决数据安全可靠地被送到远端机器
- 用户使用应用层软件,完成数据地发送和接收,而软件要进行通信就要先启动起来,而启动一个软件也就是进程创建
- 所以日常我们网络通信的本质:就是“进程间通信”,两个进程间要通信就是让两个进程看到同一份资源,这个资源就是网络,而这个网络再具体一点就是网络协议栈
问题: 当传输层即将把数据交给应用层时,但是此时应用层有很多应用,它咋知道要把数据交给哪个应用呢?
解答:所以上层要和传输层达成一种方案,让数据能够准确地交给上层,这个方案叫做“端口号”
1.2 端口号是什么
端口号:是传输层协议的内容,是一个2字节16位的整数,就是4个数字,它用来标识一个进程,告诉操作系统,当前这个数据从传输层要交给应用层的哪一个应用
- 端口号无论对于客户端还是服务器,都能唯一地标识该主机上的一个网络应用层的进程,这点类似于进程的PID,一个端口号只能被一个进程占用
- 在公网上,ip地址能表示唯一的一台主机,端口号(port),用来标识该主机上的唯一一个进程,所以 ip + port = 标识全网唯一的一个进程。
- 所以客户端和服务器都要有自己的ip和port,这种基于ip + port 的通信方式,我们叫做socket,后面会讲
1.3 三个问题
问题:端口号和我们的进程pid有什么区别,两者似乎都能标识该主机上进程的唯一性,那为什么不用pid要用端口号?
解答:
- 不是所有的进程都需要网络通信,但是所有进程都要有pid --> 告诉我们网络是需要单独设计的
- 实现端口号,是为了实现系统和网络的功能解耦,因为系统可能会变,当两者分开设计后,一方收影响就不会影响对方或者对对方的影响大大降低
问题:服务器和客户端是如何知道对方的端口号的?
解答:
首先是客户端如何知道服务器端口号的:
- 服务器和端口号都是同一家公司开发的,所以要想客户端知道端口号,那么这个端口号必须是众所周知的,精心设计的被客户端知晓的
- 这个一般由开发商做的,安装的时候将端口号或者ip直接内置进去了
然后是服务器如何知道客户端端口号的:
- 每次请求都是客户端主动发起的,所以让服务器知道客户端端口号是比较容易的
问题:传输层是如何根据端口号讲数据准确交给应用层众多进程中的那一个对应进程的?
解答:
- 操作系统会在传输层给我们形成一张哈希表,里面存的都是各个进程PCB的指针
- 首先进程绑定端口号的时候,就根据哈希算法找到对应位置,如果这个位置没有PCB指针,就把该进程的PCB指针存进去,当把PCB指针放进哈希表时,就可以认为该进程绑定了端口号
- 然后客户端的报文到了服务器的传输层时,传输层就拿着报文中的端口号在哈希表里做哈希运算,找到哈希表对应位置的进程PCB指针,进而找到对应进程,完成传输层将数据交给应用层的某个具体进程
- 一个进程可以绑定多个端口号,但是一个端口号只能绑定一个进程,因为哈希表是这样规定的,比如哈希表多个位置可以放同一个指针,但是同一个位置只能放一个指针
二,认识Tcp协议和Udp协议
网络协议栈是贯穿整个体系结构的,在操作系统层,应用层和驱动层都有自己的协议。而离我们普通程序员最近的就是使用系统调用接口实现网络通信了,所以离我们最近的就是传输层,传输层应用最广泛最受欢迎的两种协议就是TCP协议和UDP协议了
TCP协议
Tcp:传输控制协议(Transmission Control Protocol),是一种面向连接的,可靠的,基于字节流的传输层协议。
- 如果两台主机想通过Tcp进行数据通信,那么必须先建立好连接道路,并确保建立成功后才进行数据传输
- 同时,Tcp协议也是保证数据传输可靠的协议,数据在传输过程中如果出现了丢包,乱序等情况,Tcp协议都有对应的解决方法,具体我们后面再讲
UDP协议
UDP:用户数据报协议(User Datagram Protocol),是一种无需建立连接,不可靠的,面向数据报的传输层协议
- 如果两台主机要使用Udp通信,无需建立连接,一方根据IP和端口直接就将数据发送给对方,这也就意味着Udp协议是不可靠的,中途出现丢包,乱序等情况,Udp都不会去处理
问题:Tcp比Udp可靠,那为啥传输层要这两种协议同时存在呢?
解答:
- 其实这里的“可靠”和“不可靠”都是中性词,无褒贬含义,就和化学里的“惰性”一样,只是描述某个东西的物理特征,并不是说这个物理懒之类的
- 保证可靠是需要成本的,而相反,不可靠相反的就是简单,TCP在比如说银行转账,微信支付的时候,底层必须是TCP协议,而UDP通常在直播,信息流视频流做数据大量派发的场景有用
- TCP虽然是可靠传输,但并不是万能的,它是保证在网络连通且链接较强的时候处理一些数据丢失问题,也就意味着Tcp的传输效率是没Udp高的,Tcp会在底层做更多的工作
三,网络字节序
计算机在存储数据时是有大小端的概念的:
- 大端:数据的高字节内容保存在内存的低地址处,低字节保存在内存的高字节处
- 小端:数据的低字节内容保存在内存的低地址处,高字节保存在内存的高字节处
如果编写的程序只在本地机器上运行,那么是不需要考虑大小端转换的问题的;但是到了网络通信时,是两台主机在进行进程间通信了,那么这两台主机采用的存储方式可能不一样,比如大端机器传数据给小端机器,那么小端机器解析出来的数据就和大端机器是不一样的
所以我们解决上面的问题,为此:TCP/IP 协议 规定,网络数据流都要采用大端字节序:
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。
- 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。
- TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。
- 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据。
- 如果当前发送主机是小端,就需要先将数据转成大端,否则就忽略,直接发送即可。
注意:所有的大小端的转化工作由操作系统来完成,因为该操作属于通信细节,不过也有部分的数据需要我们自行进行处理,比如IP的端口号
同时,为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换:
#include<arpa/inet.h>uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntonl(uint32_t netlong);
uint16_t ntons(uint16_t netshort);
- h表示host,n表示network,l表示32位长整数,s表示16位短整数。
- 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
- 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。
- 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
四,socket编程接口
4.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);
4.2 sockaddr结构
可以发现,上面的每个接口的参数都有一个结构体指针 struct sockaddr* addr,下面详细介绍一下:
套接字有三种:
- 1,域间套接字编程:套接字不仅支持跨网络的进程间通信,也支持本地的进程间通信,用的就是这个
- 2,原始套接字编程:通常用来编写一些网络工具,比如监测,抓包等
- 3,网络套接字编程:重点使用传输层,通过TCP和UDP实现用户间的网络通信
所以最开始的套接字结构体提供了两种:
- sockaddr_un:用于本地
- sockaddr_in:用于跨网络
套接字种类不同,就有不同的应用场景,但是网络接口的设计者不想搞三套,计划将网络接口统一抽象化;而网络接口要想统一,那么接口的参数类型必须一致,所以就设计了sockaddr这个结构体:

- 之后在传参数的时候只要传sockaddr这一个就可以了,在设置参数之前就可以往这个结构体添加字段,这点下一篇简单Udp和程序的代码中会具体表现
- 如上图,在调用socket API 的那些接口时,这些API就可以提取 sockaddr 内部的头16字节进行识别,进而得出我们是要进行网络通信还是本地通信,执行对应的操作,完成接口的统一
- 注意:实际在进行网络通信时,定义的还是 sockaddr_in 这样的结构体,只是在传参的时候将该结构体的地址类型强制转换位 sockaddr* 罢了
问题:为啥不用C语言的万能参数 void* 来代替struct sockaddr* 类型呢?
解答:最简单的原因就是,设计网络接口时,C语言还不支持void*传参,而在后面C语言支持void*之后,也很难改回来了,因为这些接口都是系统接口,而系统接口是上层软件接口的基石,所以系统接口不是想改就改的,所以现在的网络接口依旧保留了sockaddr
相关文章:
计算机网络(二) —— 网络编程套接字
目录 一,认识端口号 1.1 背景 1.2 端口号是什么 1.3 三个问题 二,认识Tcp协议和Udp协议 三,网络字节序 四,socket编程接口 4.1 socket常见API 4.2 sockaddr结构 一,认识端口号 1.1 背景 问题:在进…...
二百五十九、Java——采集Kafka数据,解析成一条条数据,写入另一Kafka中(一般JSON)
一、目的 由于部分数据类型频率为1s,从而数据规模特别大,因此完整的JSON放在Hive中解析起来,尤其是在单机环境下,效率特别慢,无法满足业务需求。 而Flume的拦截器并不能很好的转换数据,因为只能采用Java方…...
Qt项目使用Inno Setup打包(关于打包中文乱码的解决)
关于打包好的文件乱码解决方法 打包好的文件中文乱码,就是编码格式出现了问题,更改一下中文脚本编码格式,在官网Inno Setup Translations下载好中文脚本 点击下载,然后另存为 得到ChineseSimplified.isl.txt文件后&#…...
HTML和HTML5有什么区别
HTML(超文本标记语言)是构建网页的基础,而HTML5是HTML的最新版本。虽然HTML和HTML5在许多方面相似,但HTML5引入了许多新的特性和改进,使得网页开发更加高效和功能丰富。 一、HTML概述 HTML,即超文本标记语…...
Collections
Collections 是 Java 中的一个实用工具类,提供了一系列静态方法来操作集合。以下是其详细介绍: 前置知识 在 Java 中,可变参数(Varargs)允许方法接受可变数量的参数。使用可变参数时,可以传递任意数量的参…...
fastreport打印trichedit分页问题的解决
用fastreport来打印richedit里面的内容。刚开始放一个frxrichview组件到报表上,然后在 var str: TMemoryStream; begin begin str: TMemoryStream.Create; CurrRichRecord.richedit.Lines.SaveToStream(str); str.Position: 0; tfrxRichview(fr…...
【MeterSphere】vnc连接不上selenium-chrome容器
目录 一、现象 二、查看配置文件 docker-compose-seleniarm.yml 三、处理 3.1 删除上图当中的三行 3.2 msctl reload 3.3 重新连接 前言:使用vnc连不上ms的selenium-chrome容器,看不到里面运行情况,以前其实可以,后来不行…...
mysql explain分析
目录 思维导图 id select_type SIMPLE PRIMARY SUBQUERY DEPENDENT SUBQUREY UNCACHEABLE SUBQUREY: UNION UNION RESULT DERIVED MATERIALIZED table partitions type ALL index range ref eq_ref const system possible_keys keys key_l…...
[论文笔记]Circle Loss: A Unified Perspective of Pair Similarity Optimization
引言 为了理解CoSENT的loss,今天来读一下Circle Loss: A Unified Perspective of Pair Similarity Optimization。 为了简单,下文中以翻译的口吻记录,比如替换"作者"为"我们"。 这篇论文从对深度特征学习的成对相似度优化角度出发,旨在最大化同类之间…...
Windows .NET8 实现 远程一键部署,几秒完成发布,提高效率 - CICD
1. 前言 场景 (工作环境 一键部署 到 远端服务器 [阿里云]) CICD 基本步骤回顾 https://blog.csdn.net/CsethCRM/article/details/141604638 2. 环境准备 服务器端IP:106.15.74.25(阿里云服务器) 客户端࿱…...
echarts 水平柱图 科技风
var category [{ name: "管控", value: 2500 }, { name: "集中式", value: 8000 }, { name: "纳管", value: 3000 }, { name: "纳管", value: 3000 }, { name: "纳管", value: 3000 } ]; // 类别 var total 10000; // 数据…...
标准IO与系统IO
概念区别 标准IO:(libc提供) fopen fread fwrite 系统IO:(linux系统提供) open read write 操作效率 因为内存与磁盘的执行效率不同 系统IO: 把数据从内存直接写到磁盘上 标准IOÿ…...
【conda】Conda 环境迁移指南:如何更改 envs_dirs 和 pkgs_dirs 以及跨盘迁移
目录 迁移概述一、conda 配置文件1.1 安装 Conda 后的默认目录设置1.2 查看当前 .condarc 配置 二、更改 Conda 的 envs_dirs 和 pkgs_dirs 设置2.1 使用 conda config 命令Windows 和 Linux 系统 2.2 手动编辑 .condarc 文件Windows 系统Linux 系统 2.3 验证设置 三、迁移 Con…...
脏页写入磁盘的过程详解
脏页写入磁盘的过程 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了保证数据的一致性和持久性,数据库系统需要在适当的时候将脏页写入磁盘。了解脏页写入磁盘的过程对于理解数据库的内部工作机制和优化性能至关重要。 二、触发脏页写入的条件…...
数据结构——单链表实现和注释浅解
关于单链表的基础部分增删查改的实现和一点理解,写在注释里~ SList.h #pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h>//定义节点的结构 //数据 指向下一个节点的指针 typedef int SLTDataType;typedef struct SListNo…...
滑动窗口系列(同向双指针)/9.7
新的解题思路 一、三数之和的多种可能 给定一个整数数组 arr ,以及一个整数 target 作为目标值,返回满足 i < j < k 且 arr[i] arr[j] arr[k] target 的元组 i, j, k 的数量。 由于结果会非常大,请返回 109 7 的模。 输入&…...
C# 窗体中Control以及Invalidate,Update,Refresh三种重绘方法的区别
在 C# 中,Control 类是 Windows Forms 应用程序中所有控件的基类。它提供了控件的基本功能和属性,这些功能和属性被所有继承自 Control 类的子类所共享。这意味着 Control 类是构建 Windows Forms 应用程序中用户界面元素的基础。 以下是 Control 类的一…...
缓存类型以及读写策略
缓存(Cache)是一种高效的数据存储技术,旨在提高数据访问速度。 它将频繁访问或最近使用的数据临时存储在更快速但较小的存储介质(如内存)中,以减少从较慢的存储设备(如硬盘或远程服务器&#x…...
自动驾驶---Motion Planning之轨迹拼接
1 背景 笔者在之前的专栏中已经详细讲解了自动驾驶Planning模块的内容:包括行车的Behavior Planning和Motion Planning,以及低速记忆泊车的Planning。 本篇博客主要聊一聊Motion Planning中轨迹拼接的相关内容。从网络上各大品牌的车主拍摄的智驾视频来看…...
没资料的屏幕怎么点亮?思路分享
这次尝试调通一个没资料的屏幕,型号是HYT13264,这个是淘宝上面的老王2.9元屏,成色很好但是长期库存没有资料和代码能点亮,仅仅只有一个引脚定义。这里我使用Arduino Nano作为控制器尝试点亮这个模块。 首先,已知别人找…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
