计算机网络(二) —— 网络编程套接字

目录

一,认识端口号

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

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

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

相关文章

网络安全运维培训一般多少钱

在当今数字化时代&#xff0c;网络安全已成为企业和个人关注的焦点。而网络安全运维作为保障网络安全的重要环节&#xff0c;其专业人才的需求也日益增长。许多人都对网络安全运维培训感兴趣&#xff0c;那么&#xff0c;网络安全运维培训一般多少钱呢? 一、影响网络安全运维培…

算法训练营——day4螺旋矩阵

1 螺旋矩阵II-力扣59&#xff08;中等&#xff09; 1.1 题目&#xff1a;螺旋矩阵II 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&…

算法学习:滑动窗口

题目 滑动窗口 滑动窗口的题目在解决统计连续带特殊要求的元素串问题时作用巨大。逃离仅仅只是套路学习的黑洞&#xff0c;我认为这种方法在无序的统计中&#xff0c;找到了有序的切入点。初看题目时&#xff0c;可以想到的统计方法有很多&#xff0c;但实现在计算机上则必须有…

贝锐蒲公英远程视频监控方案:4G入网无需公网IP,跨品牌统一管理

在部署视频监控并实现集中监看时&#xff0c;常常会遇到各种挑战。比如&#xff1a;部分监控点位布线困难、无法接入有线宽带&#xff0c;或是没有固定公网IP&#xff0c;难以实现远程集中监看&#xff1b;已有网络质量差&#xff0c;传输延迟大、丢包率高&#xff0c;远程实时…

【王树森】BERT:预训练Transformer模型(个人向笔记)

前言 BERT&#xff1a;Bidirectional Encoder Representations from TransformerBERT是用来预训练Transformer模型的encoder的本节课只讲述主要思想BERT用两个主要思想来训练Transformer的encoder网络&#xff1a;①随机遮挡单词&#xff0c;让encoder根据上下文来预测被遮挡的…

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&…

win12R2安装.NET Framework 3.5

一丶安装原因 因此插件的缺失, 有些软件或系统不支持安装. 二丶安装步骤 1丶下载.NET Framework 3.5 点击插件下载, 提取码: 1995, 下载完成之后解压到想要安装的位置上. 2丶打开 服务器管理器 3丶点击: 管理 -> 添加角色和功能 4丶点击下一步到服务器角色, 选择web服…

Android应用开发项目式教程——序

Android技术 Android是重要的客户端技术&#xff0c;因其开源开放的特点&#xff0c;Android在其初期就迅速成长为智能手机的主流操作系统&#xff0c;近年来更进一步成为智能电视、智能车载终端等智能设备的主流操作系统&#xff0c;其活跃设备数量已经超过30亿台&#xff0c…

通用内存快照裁剪压缩库Tailor介绍及源码分析(一)

背景 我们知道内存快照是治理 OOM 问题及其他类型的内存问题的重要数据源&#xff0c;内存快照中保存了进程虚拟机的完整的堆内存数据&#xff0c;很多时候也是调查其他类型异常的重要参考。但是dump出来的堆转储文件.hprof往往很大&#xff0c;以 LargeHeap 应用为例&#xf…

吐血整理 ChatGPT 3.5/4.0 新手使用手册~ 【2024.09.04 更新】

以前我也是通过官网使用&#xff0c;但是经常被封号&#xff0c;就非常不方便&#xff0c;后来有朋友推荐国内工具&#xff0c;用了一阵之后&#xff0c;发现&#xff1a;稳定方便&#xff0c;用着也挺好的。 最新的 GPT-4o、4o mini&#xff0c;可搭配使用~ 1、 最新模型科普&…

XGBoost算法-上

简单解释一下xgboost这个模型 xg是一个非常强大&#xff0c;非常受欢迎的机器学习模型&#xff0c;其中最大的特色就是boosting&#xff08;改进、推进&#xff09;&#xff0c;怎么改进呢&#xff1f;就是xgboost这个算法&#xff0c;它会先建立一颗简单的决策树&#xff0c;…

虚拟机ubuntu配置opencv和opencv_contrib

前期准备 1.下载opencv和opencv_contrib源码 opencv-4.6.0&#xff1a;https://opencv.org/releases/ opencv_contrib-4.6.0&#xff1a;https://github.com/opencv/opencv_contrib 在ubuntu直接下载或者在window上下好传到虚拟机里都可以 自己找个地方把他们解压&#xf…

【Python篇】PyQt5 超详细教程——由入门到精通(终篇)

文章目录 PyQt5超详细教程前言第9部分&#xff1a;菜单栏、工具栏与状态栏9.1 什么是菜单栏、工具栏和状态栏9.2 创建一个简单的菜单栏示例 1&#xff1a;创建带有菜单栏的应用程序代码详解&#xff1a; 9.3 创建工具栏示例 2&#xff1a;创建带有工具栏的应用程序代码详解&…

Banana Pi BPI-SM9 AI 计算模组采用算能科技BM1688芯片方案设计

产品概述 香蕉派 Banana Pi BPI-SM9 16-ENC-A3 深度学习计算模组搭载算能科技高集成度处理器 BM1688&#xff0c;功耗低、算力强、接口丰富、兼容性好。支持INT4/INT8/FP16/BF16/FP32混合精度计算&#xff0c;可支持 16 路高清视频实时分析&#xff0c;灵活应对图像、语音、自…

多个路由器级联实现子网的方式

好久没写博客啦&#xff0c;最近搬家&#xff0c;换了网络环境&#xff0c;简单记录一下网络配置。 拓扑图就不画了&#xff0c;光猫 - > 华为TC7102路由 -> 华为AX2 Pro路由 -> 各种设备&#xff0c;简单表示就是这样。 原因是第一个路由是房东的&#xff0c;我希望自…

宝塔部署Vue项目解决跨域问题

一、前言 使用宝塔面板部署前端后端项目相比用命令行进行部署要简单许多&#xff0c;宝塔的可视化操作对那些对Linux不熟悉的人很友好。使用宝塔部署SpringBoot后端项目和Vue前端项目的方法如下&#xff1a; 1、视频教程 2、文字教程1 3、文字教程2 以上的教程完全可以按照步骤…

视频智能分析平台LntonAIServer视频质量诊断功能花屏、抖动、遮挡等检测

LntonAIServer新增了视频质量诊断功能&#xff0c;该功能专注于提升视频监控系统的稳定性和可用性&#xff0c;主要通过自动化检测来识别视频流中常见的质量问题&#xff0c;比如花屏、抖动、遮挡等问题。这些问题是影响视频监控效果的主要因素之一&#xff0c;而自动化的检测能…

解决el-table中使用el-input无法聚焦问题

在el-table中点击单元格时使用el-input或其他表单组件编辑单条数据。会出现聚焦不上的问题&#xff0c;需要手动点击才能够聚焦。究其原因是因为点击单元格时页面已自动聚焦到单元格&#xff0c;此时无法自动聚焦到对应的表单&#xff0c;需要手动设置。 <template><e…

操作系统八股总结

操作系统八股总结 操作系统的四大功能&#xff1a;进程控制&#xff0c;内存管理&#xff0c;设备管理&#xff0c;文件管理进程的定义:并发程序的执行&#xff0c;进程的同步与互斥进程的状态&#xff1a;创建&#xff0c;终止&#xff0c;就绪&#xff0c;运行&#xff0c;阻…

图论(2)

一、度 度统计的是一个节点上又多少条边 度出度入度 出度&#xff1a;统计以该节点为起始点箭头指向外面的边的条数 入度&#xff1a;统计箭头指向该节点的边数 度为1的节点为悬挂节点&#xff0c;边为悬挂边 用矩阵计算节点的度 二、握手定理 比如这里第一个集合里面有三…