前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >初识Linux · Socket理论基础

初识Linux · Socket理论基础

作者头像
_lazy
发布2025-03-08 09:44:30
发布2025-03-08 09:44:30
4100
代码可运行
举报
文章被收录于专栏:Initial programmingInitial programming
运行总次数:0
代码可运行

前言:

在前文我们介绍了什么是协议,网络的发展史,以及协议的本质是什么,并且介绍了网络通信分为几种,一种的局域网通信,一种是本地通信,其中局域网通信分为了大致三种,令牌环,以太网,以太网的变种-无线WLAN,还介绍了OSI七层模型,TCP五层/四层模型等。

以上都是为网路的理论知识做铺垫,按道理来说我们应该为编程打下知识铺垫展开一个宏大的理论描述,但是呢,博主认为光是理论,没有快速的进入到实现是比较容易陷入“纯理论内耗”的,所以本文简单扼要的续一下网络理论知识,简单的描述一下铺垫编程所需要的理论知识就进入到实战部分了。

网络理论基础

ip地址

· ip地址是用来标识网络中的主机的地址,一般分为IPv4和IPv6

· 对于IPv4来说,IP地址是一个4字节,32位的整数

· 常用“点分十进制”来表示一个IP地址,其中范围一般是0 - 255

MAC地址

在数据传输的过程一般涉及到的两个地址,一个是IP地址,一个是MAC地址,其中目的IP地址表示的是最终目的的,MAC地址表示的是即将到达的下一个地址,其中IP地址一般不会变化,除了源IP地址,这个点后面解释,所以MAC地址是会一直变化的。

IP地址的作用是屏蔽底层网络差异

Socket编程基础

对于Socket编程,我们先不用纠结什么是Socket,你就算先去翻译Socket也没有用,因为它本来的意思是插座,你看了你更迷糊了。

我们要先来理解几个概念,一个是目的IP,一个是源IP,一个是端口号,把这三个我们理解了,我们就能理解什么是Socket了。

目的IP,源IP

因为IP地址是用来标识网络中的唯一的主机的地址的,所以目的IP,也就是收到数据包的主机的地址,源IP也就是发送数据包的主机的地址。

端口号

有了主机的唯一地址,还没有万事大吉,因为发送数据包的并不是你的这台电脑,而是你电脑中的不同进程,比如QQ,微信,抖音等,那么有意思的来了,我们既然要引入一个专门的标识号来指定某个进程,为什么不用pid来指定是哪个进程呢

最主要的目的是为了解耦合,因为pid本身是属于系统级别的概念,而我们要进行的是网络通信,如果我们使用了pid,也就是让系统进程管理和网络通信管理强耦合,这是不易于管理的。

所以,前辈额外引入了一个概念,也就是端口号,它表示一个进程,那么端口号port + 目的IP地址就可以表示互联网中的唯一的一个进程,那么其中:

port + IP = socket,我们将ip + port叫做套接字socket,这也就是Socket编程的由来。

TCP/UDP协议

对于TCP来说,它的特征是:

1. 传输层协议 2.有连接 3.可靠传输 4.面向字节流

对于UDP来说,它的特征是:

1.传输层协议 2.无连接 3.不可靠传输 4.面向数据报

我们要注意到的一个点是,以上的描述是特征,而非缺点。比如你看TCP的可靠传输,比如传输的数据包发生了乱序,倒序的情况,它是可以将数据包恢复的,相反的UDP就不可以。

那么面向字节流和面向数据报等的特征区别,我们到后面详细介绍。在这里我们清楚一个点就是,存在即合理,这二者各有神通,我们不应该简单的凭借四个特点就否定它们。

不过我们现在可以得到的结论是UDP比TCP简单,因为UDP不用建立连接,不用考虑数据的问题,直接就传送就可以了。

所以在下一篇文章,我们将会简单的使用UDP协议完成一个通信服务。

说到通信,你看,网络通信的本质是什么?

主机A中的唯一进程和主机B中的唯一进程进程通信,这不就是进程间通信吗?


网络字节序

提到网络字节序,我们先来简单重温一个旧知识,什么是大小端机器

这里给一个方便记忆的好技巧,记住小小小就可以了。

因为小权重的数放在低地址处的机器是小端机器

好了,对应的网络字节序也是差不多的观点,如果主机A是小端机器,发送的数据是小端的形式,主机B是大端机器,接受的数据是大端形式的数据进行解析,那这不炸了吗?数据直接就乱套了。

所以我们就需要一个解决方法用来解决发送数据的大小端问题了,我们可以在发送数据上进行标识,也可以在进行各种序列化,但是这一切都麻烦了。

对于TCP/IP协议,索性就直接规定:网络数据流应采用大端字节序,即低地址高字节

在这后面还有一个涉及的内容就是序列化和反序列化,这个点我们后面再谈。

那么光这样规定肯定不行,如果发送的机器是小端机器,我们就应该想办法转为大端,所以库函数提供了一些函数用来进行数据序列转换:

这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位 短整数。

这是对应描述,具体使用我们移步到下一篇文章就可以知晓了。


Socket常见API

有了socket编程的理论知识,我们现在先了解一下对应的接口,比如我们需要接口创建Socket套接字,需要绑定对应的端口号,对于TCP来说,还有监听,接收,建立连接的API:

代码语言:javascript
代码运行次数:0
复制
 // 创建 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);

那么对于上面的参数我们使用的时候会提及,现在需要解决一个问题就是,什么是struct sockaddr?

对于这个结构体,我们需要介绍对应的三个结构体:

其中socket编程涉及到了三个结构体分别是struct sockaddr,struct sockaddr_in, struct sockadd_un

那么为什么会有这么多呢?因为进程通信可以分为局域网通信和本地通信,所以add_in这个结构体就是用来局域网通信的,un结构体就是用来本地通信的。

可是对于通信来说,API做太多了实在麻烦,所以其实你看上面的API的参数都是addr的指针类型,对于in和un两种结构体,传参的时候强转一下即可,那么对于一些公共的元素,“继承”下来就好了~~

所以这也算是C语言中的多态了。

具体的使用我们放在后面再介绍。这里理解有一个基类的存在即可。

对于它们结构体里面的一些元素我们就放到下一篇文章详解就行了。

感谢阅读!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:
  • 网络理论基础
    • ip地址
    • MAC地址
  • Socket编程基础
  • TCP/UDP协议
  • 网络字节序
  • Socket常见API
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档