【网络】-- 网络编程套接字(铺垫、预备)

news2024/11/20 20:19:38

目录

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

认识端口号

端口号

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

套接字

认识TCP与UDP协议

网络字节序

socket编程接口

socket 常见API

sockaddr结构


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

就如同我们唐僧的取经路:

  • 唐僧的出发地到目的地:东土大唐 -> 西天。
  • 唐僧的长途跋涉途中:东土大唐 -> …… -> 车迟国 -> 黑风岭 -> …… ->西天。

  • 源IP -> 目的IP:是永远都不会改变的。
  • 源MAC -> 目的MAC:会根据当前所处的位置,不断的进行变化。

目的MAC是受目的IP的影响的,以此到达目地的IP。

认识端口号

        我们所使用IPV4,在经过互联网的大爆发,人人拥有上网设备,甚至是几个上网设备,而公司之类的也需要配IP。仅仅IPV4的32位字节,肯定是远远的不够的,而现在之所以还能正常的使用。原因是存在一种技术,叫做NAT技术,其划分了对应的局域网公网

        而不论是在什么网段,在各自的特定网段当中,IP都要表示该对应主机的唯一性

#问:把数据送到对方的机器上是目的吗?

        不是的,就如同我们在使用一个app的时候,如:抖音,其所播放的视频内容是经过网络申请,然后抖音的服务器将视频内容数据发送给抖音app,那么为什么不是发送给淘宝app偏偏就是要发送给抖音app?就是因为是软件客户端(抖音)申请的数据,然后将数据申请通过给我们的主机,让主机(手机)帮它去申请,所以数据到主机都还是没有结束的。

  • 主机(手机)上层的软件客户端在跑。
  • 服务器:上层的服务器软件在跑。

        所以通讯的时候,并不是两个机器在通讯,而是二者上层的软件在通讯。而对应的软件就是程序员所写的对应的代码,编译所形成的二进制程序。所以准确的来说,因为客户端也是需要打开才哪能申请数据、接收数据。

        (对于上面的问题)不是的,真正的网络通信过程,本质上其实是进程间通信!将数据在主机间转发仅仅是手段,(一般在网络通讯的时候真正网络通讯的本质是进程间通讯,但是因为跨主机了,所以我们需要将数据先在主机间进行通讯)机器收到之后,需将数据交付给指定的进程!

#问:将数据教给对应的主机之后,如何保证的主机可以将对应的数据交付给特定的进程? 

        利用端口号!

端口号

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

        端口号是标识特定主机的上的网络进程的唯一性!即:端口号在特定的主机上有若干个进程,端口号不能够被同时绑定,只能够被一个进程进行关联。

        所以任何一个发出的报文:一定有IP,port(端口号)。

#问:在Linux的进程中,有一个进程PID,进程PID也标定了进程的唯一性,那进程PID与端口号的关系是什么?

        重点是他们标识进程唯一性的能力,进程PID是进程管理的范畴,如果网络也使用进程PID来标识唯一性,那么网络的模块和进程管理的模块就黏在一起了,就会导致两个毫不相关的模块产生关联这是没有任何意义的,单独实现一个端口号提供给网络模块使用,实现网络模块与其他的模块的解耦。

        并且不是所有进程都需要端口号,但是是一定所有进程都需要进程PID。

#问:一个进程可以和多个端口号绑定吗?

        一个进程可以和多个端口号绑定,我们想绑定几个就绑定几个都没有任何问题。只要一个端口号只能和一个进程关联即可。

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

        为了让我们进行更好的数据通信,客户端有自己的端口,服务端也有自己的端口。客户端向服务器发送消息,客户端的端口叫做源端口,服务端的端口叫做目的端口。如果是服务端向客户端发数据,客户端的端口叫做目的端口,服务端的端口叫做源端口

        谁发数据谁就是,谁收数据谁就是目的

套接字

  • SRC_IP:标定互联网中的唯一的一台主机。
  • SRC_PORT:标定主机中唯一的进程。

套接字:SRC_IP + SRC_PORT。

        网络通讯的本质:进程间通信,套接字编程。

认识TCP与UDP协议

        传输层是处于操作系统的,并且是离上层应用层最近的,应用层所使用的接口都是TCP协议 / UDP协议提供的。

认识UDP协议

UDP (User Datagram Protocol 用户数据报协议 一个直观的认识
  • 传输层协议
  • 无连接 —— 不用写代码的时候刻意连接,直接发送数据
  • 不可靠传输 —— 可能会出现网络丢包的问题 / 数据包重复乱序等问题
  • 面向数据报

认识TCP协议

对TCP (Transmission Control Protocol 传输控制协议 一个直观的认识。
  • 传输层协议
  • 有连接—— 写代码的时候需要刻意连接
  • 可靠传输
  • 面向字节流

        UDP协议就如同发短信,无需经过对方的同意,直接发送即可。TCP协议就如同打电话,需要经过对方的同意,不能直接进行通话,需要对方接听。

#问:为什么UDP协议不可靠,却还是要选择UDP协议?

        现在的网络中,出现丢包的问题概率不大,即便出现了丢包问题,有些场景下也是可以容忍的,更重要的是不可靠是特点,可靠也是特点,但是不可靠看起来像缺点,但是它的反面就是没有为了让对应的程序,变得可靠,而做了更多得工作。可靠性是需要付出大量的编码,和数据得处理的,设置更多的策略,更复杂。

        TCP协议就是什么都要管,而UDP协议就是只要将数据发出去了就行了。一个更安全,一个更简单。在日常编写中,除非十分的适合UDP协议,其余情况都是使用TCP协议。比如:视频、直播等,在播放的时候出现声音丢失一下、卡一下,就有可能是使用UDP协议,而出现的丢包的情况。

网络字节序

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

什么是大端小端:
        大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
        小端
(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。

#问:那么如何定义网络数据流的地址呢?

        首先,我们需要知道,两天主机如果大小端不一致,经过网络通讯时必然会导致双方无法正常的通信。

解决这个问题,猜测做法:

        无论是A -> B发,B -> A发:都把自己的大小端信息特征带上,对方主机提取数据时就先对大小端特征 —— 也很逗,因为大小端特征也是对应的存储,怎么识别?

于是网络就直接规定了:

        网络规定:所有的网络数据,都必须是大端!

        发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址

  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。
  • 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据。
  • 如果当前发送主机是小端,就需要先将数据转成大端。否则就忽略,直接发送即可。

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

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

socket编程接口

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

常见的套接字:

  • 域间socket —— 本主机内的进程间通信,也称作:基于套接字式的管道通信。
  • 原始socket —— 通常用于编写很多很多的工具,一般我们在应用层写代码用的是传输层接口,原始socket允许我们绕过传输层,直接使用网络层,甚至使用网络层以下的底层。
  • 网络socket

        因为套接字的不同,所以理论上,是三种应用场景,对应的应该是三套接口。但是Linux在设计的时候,不想设计过多的接口,于是就将所有的接口进行了统一。

sockaddr结构

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

#:sockaddr结构的出现。

        在上述图中,以及前面将常见的三种套接字的介绍,套接字不仅需要支持跨网络的进程间通信,还需要支持本地的进程间通信(域间socket)。在进行跨网络通信时我们需要传递的端口号和IP地址,所以就是必须使用上述的 struct sockaddr_in 结构体。而本地通信(域间socket)则不需要,因此使用上述的 struct sockaddr_un 结构体,其中类型对应的不同,涉及的参数最终导致的是需要两个接口。就是因为 struct sockaddr_in 结构体是用于跨网络通信的,而 struct sockaddr_un 结构体是用于本地通信的,是不同的。

        所以,为了让套接字的网络通信本地通信能够使用同一套函数接口,于是就出现了 struct sockaddr 结构体,该结构体与 struct sockaddr_in  struct sockaddr_un 的结构都不相同,但这三个结构体头部的16个比特位都是一样的,叫做地址类型,就是表明其是网络通信的套接字还是本地通信的套接字。

        可以说: struct sockaddr 很像一个基类, struct sockaddr_in  struct sockaddr_un 是其的派生类。所以我们的传递完全可以传递 struct sockaddr ,最终是什么结构体,完全看完全看结构体头部的16个比特位的对应。

总结:

  • IPv4和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结构体指针做为参数。

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

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

相关文章

阿尔法开发板 .bin 文件烧写

一. IMX6ULL 开发板简介 IMX6ULL 开发板是正点原子提供的阿尔法开发板,所用芯片为恩智浦,基于 Cortex-A7 架构。 这里介绍一下裸机篇中,关于如何将 .bin 文件烧写进 SD 卡,从而设备运行程序。 二. xx.bin 文件烧写 IMX6ULL支…

句子的改写和扩写

目录 1.句子改写 2.句子扩写 (不低于15个句子算是长句子,不能太多长句子) 1.句子改写 我绝不会嫁给你的。 如果你是世界上最后一个男人,我就去寺庙。 If you married me,I would jump into the well. 如果你嫁给我,我…

【Java学习笔记】5.Java 基本数据类型

Java 基本数据类型 变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。 因此,通过定义不同类型的变量&#xf…

计算机网络的166个概念你知道几个 第三部分

广播:我们一般小时候经常会广播体操,这就是广播的一个事例,主机和与他连接的所有端系统相连,主机将信号发送给所有的端系统。 多播:多播与广播很类似,也是将消息发送给多个接收主机,不同之处在于…

最近一年我都干了什么——反思!!

过去一年不管是学习方式还是心态上都和以往有了许多不同的地方,比较昏昏沉沉。最近慢慢找到状态了,就想赶紧记录下来。 学习 在学习新技术的过程中开始飘了,总感觉有了一些开发经验后就觉得什么都不用记,知道思路就行遇到了现场百…

15、正则表达式

目录 一、元字符 二、限定修饰符 一、元字符 正则表达式通常被用于判断语句中,用来检查某一字符串是否满足某一格式。正则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。例如,“\\d”表示数字0~9中的任何…

BUU [ZJCTF 2019]Login

这是一道让我感觉很淦的题,整一天了才大致了解了来龙去脉 开始: 首先丢到虚拟机checksec一下看看有啥保护措施: 看到开了Canary,就已经感觉不妙了,接着丢到IDA里看看啥情况 一看,是令人痛苦的c风格的代码…

IDEA中使用Tomcat的两种方式:集成本地Tomcat使用Tomcat Maven插件

一、前言 在IDEA中创建完一个Maven Web项目,并补齐了目录以后,准备使用Tomcat时,就需要在自己创建的项目中去部署Tomcat,前文已经介绍了如何创建Maven Web,所以这里就不多加赘述,直接讲述部署Tomcat的方法…

fastadmin后台登录页修改

直接替换就行 <!DOCTYPE html> <html lang"{$config.language}"> <head>{include file"common/meta" /}<style type"text/css">body {color: #999;background-color: #f1f4fd;background-size: cover;}a {color: #444;…

[极客大挑战 2019]EasySQL 1

[极客大挑战 2019]EasySQL 1解题POC一、解题思路之暴力破解1. 弱口令2. 暴力破解二、解题思路之万能密码1. 什么是万能密码2. 测试过程解题POC 直接点击登录获取flagflag{62f0d2ca-579e-450e-941f-5f7c23a8baf7} 一、解题思路之暴力破解 这题是万能密码&#xff0c;所以暴力破解…

推荐一个.Net Core开发的Websocket群聊、私聊的开源项目

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件&#xff0c;可用于群聊、好友聊天、游戏直播等场景。 项目简介 这是一个基于.Net Core开发的、简单、高性能的通讯组件&#xff0c;支持点对点…

面试题---CSS

面试题---CSS子绝父相下&#xff0c;子百分比的问题两栏布局问题三栏布局问题---圣杯问题(三栏&#xff0c;左右固定&#xff0c;中间自适应)。内联样式与块级样式的区别怎么让一个 div 水平垂直居中分析比较 display: none 、visibility: hidden、opacity: 0优劣和适用场景css…

Day5: platformDriver-1

Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备&#xff0c;因此大部分的驱动是平台驱动&#xff08;patform driver&#xff09; 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述&#xff1a; Platform devices are devices t…

CUDA By Example笔记--Julia集合的并行计算

目录 1--linux报错汇总 1-1 使用 nvcc 命令编译报错 1-2--使用 CMake 编译源码报错 2--源码解读 1--linux报错汇总 1-1 使用 nvcc 命令编译报错 使用 nvcc ./julia_gpu.cu -lglut -lGLU -lGL 运行时&#xff0c;显示 cannot find -lglut 的错误&#xff0c;定位 "gl_…

linux配置核查MySQL 配置规范 (Linux)_S3A3G3

linux的配置核查问题&#xff1a; 解决&#xff1a; 1.检查是否禁止mysql对本地文件存取 方法一&#xff1a;在my.cnf的mysql字段下加local-infile0 方法二&#xff1a;启动mysql时加参数local-infile0 /etc/init.d/mysql start --local-infile0 假如需要获取本地文件&#xf…

【C语言——练习题】指针,你真的学会了吗?

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨一维数组练习题&#xff1a;字符数组练习题&#xff1a;字符指针练习题&#xff1a;二维数组练习题&am…

Numpy专栏目录(长期更新)

文章目录数组基础文件与字符串多项式分布Numpy绝对可以说是支撑Python地位的最重要的包了&#xff0c;几乎所有能叫出名的Python计算库&#xff0c;都不可避免地调用了Numpy&#xff0c;Numpy官网也列出了一些&#xff0c;大致如下图这样&#xff0c;堪称科学计算领域的瑞士军刀…

计算机网络的166个概念你知道几个 第四部分

HTML&#xff1a;HTML 称为超文本标记语言&#xff0c;是一种标识性的语言。它包括一系列标签&#xff0e;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的 Internet 资源连接为一个逻辑整体。HTML 文本是由 HTML 命令组成的描述性文本&#xff0c;HTML 命令可以说…

黑猫带你学eMMC协议第28篇:eMMC的开漏和推挽模式(push-pull open drain)

本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 文章为个人辛苦整理,付费内容,已加入原创侵权保护,禁止私自转载。 文章所在专栏:《黑猫带你学:eMMC协议详解》 1 什么是开漏和推挽 1.1 推挽电路是什么 关于推挽和开漏电路,更多介绍详见我的另一篇文章…

面试热点题:环形链表及环形链表寻找环入口结点问题

环形链表 问题&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接…