网络套接字基本概念

在这里插入图片描述

1. 认识IP地址

IP协议有两个版本,IPv4和IPv6。没有特殊说明的,默认都是指IPv4
IP地址是在IP协议中, 用来标识网络中不同主机的地址。对于IPv4来说,IP地址是一个4字节,32位的整数。我们通常也使用 “点分十进制” 的字符串表示IP地址, 例如 192.168.0.1,用点分割的每一个数字表示一个字节,范围是0 - 255。

2. 认识端口号

我们光有IP地址就可以完成通信了嘛? 想象一下发qq消息的例子,有了IP地址能够把消息发送到对方的机器上,但是还需要有一个其它的标识来区分出,这个数据要给哪个程序进行解析
实际上,在进行通信的时候,不仅仅要考虑到两台主机间的交互数据,本质上,交互数据的时候,是用户和用户在进行交互。用户的身份通常是用程序来体现的。而程序一定在运行中,那么就是进程。

主机间通信的本质是:在各自的主机上,两个进程在互相交互数据。IP地址可以完成主机和主机的通信,而主机上各自的通信进程,才是发送和接受数据的一方

那么IP是确保主机的唯一性,端口号(port)是确保该主机上进程的唯一性IP+端口号=标识互联网中唯一的一个进程。也被叫做socket。所以,网络通信的本质就是进程间的通信

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

2.1 理解 “端口号” 和 “进程ID”

我们之前在学习pid 表示唯一一个进程。此处我们的端口号也是唯一表示一个进程。那么这两者之间是怎样的关系?
1.如果我们用进程ID来网络通信,那么网络和进程管理就强耦合了。
2.可能会有些进程根本不需要通信,有端口号的说明是网络进程,没有的就不考虑网络功能。就像一名学生的学号和身份证号,学号可以代表你是一名学生并且是一个人,而身份证号不能代表你是一名学生。

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

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

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

3. 认识TCP协议和UDP协议

此处我们先对TCP(传输控制协议)和UDP(用户数据报协议)有一个直观的认识,后面再详细讨论。
TCP:1.传输层协议,2.有连接,3.可靠传输,4.面向字节流。
UDP:1.传输层协议,2.无连接,3.不可靠传输,4.面向数据报

这里可靠传输和不可靠传输是什么意思呢
可靠传输是你发出的信息,可以确信这些数据被接受方收到。一般来说,可靠是通过确认和重传机制来实现的。但是需要的成本也是很高的。不可靠传输就是发出的数据不能保证接受方能够收到,这样的成本不高。

4. 网络字节序

我们已经知道:内存中的多字节数据相对于内存地址有大端和小端之分。以前我们在自己的主机里感觉没什么区别,但是在网络通信的过程中。如果我们发送方是小端,接受方是大端,那么在接受信息时,我们该怎么去判断对方是大端,还是小端呢?
网络数据流同样有大端小端之分,互联网上规定:网络中默认是大端

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

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
在这里插入图片描述
h表示host,n表示network,l表示32位长整数,s表示16位短整数
第一种是将主机字节序转换成网络字节序。
第二种是将网络字节序转换成主机字节序。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

5. sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6。然而,各种网络协议的地址格式并不相同。
这个套接字不仅要支持网络通信,也需要支持本地通信。网络通信默认叫做套接字,本地通信叫做域间套接字。
在这里插入图片描述
sockaddr_in这个结构就是网络通信,sockaddr_un这个结构就是本地通信。那么我们想既要包含网络通信,又要包含本地通信,设计socket API接口时就不能单单设计某一个,要把二者结合起来。就是sockaddr这个结构。不论传的是sockaddr_in还是sockaddr_un它们的前16位都是地址类型,那么我们先判断sockaddr的前16位是啥?然后再去强转成sockaddr_in或sockaddr_un。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值