网络编程套接字

时间:2022-01-24 23:58:33

网络编程套接字


本节重点

  • 认识IP地址,端口号,TCP协议和UDP协议的区别,网络字节序等网络编程的基本概念
  • 学习socket api的基本用法
  • 能够实现一个简单的UDP客户端/服务器

本节重点需要掌握的是:

网络编程套接字

基本概念


1. 认识IP地址
  • IP地址是在IP协议中,用来标识网络中的不同主机的地址
  • IP协议有两个版本,IPv4 和 IPv6 (默认指的是IPv4)
    1. 对于IPv4来说,ip地址是4字节,32位的整数
      表示为点分十进制格式,4个组,一个组8个位(用十进制表示)用点分割的每一个数字表示一个字节,范围是0~255
      eg:192.168.0.1
    2. 对于IPv6来说,ip地址是128位的整数
      表示方式:将128位分为8个组,一个组16位(写成4个十六进制数)
      eg: 31da:1d3:0:2f3b:2aa:ff:fe28:9c5a

源IP地址和目标IP地址是基本不变的地址 下面用唐僧师徒四人西天取经的例子来解释一下:

整个取经的过程中:
1. 源IP地址(长安)——>目标IP地址不变(西天),这整个过程中一个不变的地址
2. 到了翠云山芭蕉洞,人家会问:你从哪到哪里去?这个时候有两个回答,两个地址:第一个:从长安来去西天取经,源IP地址(长安)——>目标IP地址不变(西天);第二个:上一站(火焰山)——>下一站(积雷山摩云洞),这是在这个过程中需要经过的路,每一站(路)都有自己的ip地址和MAC地址(物理地址)。

思考:是不是只需要有ip地址就可以通信?

同样的问题,整个西天取经过程中,直到ip地址(从长安到西天),只知道这个不能完成取经;需要直到从长安的谁那得到的信息到西天的谁那拿经(唐太宗——>如来佛);有了ip地址(长安 西天)和端口号(唐太宗 如来佛)才能完成取经。——>引出了下面的端口号的概念。


2.. 认识端口号
  • 端口号(port)是传输层协议中的内容
  • IP地址+端口号就是套接字
  • 套接字通信本质就是进程间通信(而其中所看到的公共资源就是:网络)

下面对端口号做以解释:

  1. 端口号:2字节16位的整数;
  2. 端口号用来标识进程的,告诉操作系统,当前的这个数据要交给哪一个进程来处理
  3. IP地址+端口号(套接字) 能够标识网络上的某一台主机的某一个进程
  4. 一个端口号只能一个进程占用(唯一性)
端口号port和进程id的区别:
  1. 都是标识进程的,pid是表示唯一进程的,端口号也是唯一表示一个进程的
  2. 进程id: 所有的进程都有id
  3. 端口号:只有网络通信时,进程才会有端口号

另外:一个进程可以绑定多个端口号,而一个端口号不能被多个进程绑定
用10086的例子做以解释 :

一个进程可以绑定多个端口号:
我们打给10086(一个进程),然后人工服务时会有很多个客服人员,然后这个时候会给我们安排客服人员转接电话,而这个客服人员所有的电话就是端口号,有很多个客服人员都有接通电话的可能,所以说一个进程可以绑定多个端口号。
一个端口号不能被多个进程绑定:
一个客服人员(一个端口号)只能接通一个人的电话,而不能同时接通好几个人的电话

其中源端口号和目的端口号就是上面例子中的唐太宗和如来佛


3. TCP协议和UDP协议的区别:
  • TCP协议:传输控制协议

特点:

  1. 传输层协议
  2. 有连接
  3. 可靠传输
  4. 面向字节流
    • UDP协议:用户数据报协议

特点:

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

4. 网络字节序

首先我们回顾一下大端和小端:
1. 大端和小端是按照什么来划分的?
答:字节。因为每一个地址单元对应一个字节。
2. 地址:分为 高地址 低地址
3. 数据:分为 高位 地位
4. 大端模式:用高地址存放数据低位,用低地址存放数据高位
eg: 32位的数0X12345678在CPU内存中存放的方式(假设0X4000表示低地址):

内存地址 0X4000 0X4001 0X4002 0X4003
存放的内容 0X12 0X34 0X56 0X78

5. 小端模式:用高地址存放数据高位,用低地址存放数据低位
eg: 32位的数0X12345678在CPU内存中存放的方式(假设0X4000表示低地址):

内存地址 0X4000 0X4001 0X4002 0X4003
存放的内容 0X78 0X56 0X34 0X12
  • TCP/CP协议规定,网络数据流应采用大端字节序,即低地址高字节
  • 发送主机:
    1.将数据发送到发送缓冲区按到地址从低到高的顺序发出;即:先发的数据——低地址,后发的数据——高地址
    2.在缓冲区的处理就是:如果是发送端是小端,转为大端,否则忽略
  • 接受主机:
    1.接受主机把从网络上接到的字节序保存在接受缓冲区端,也按照地址从低到高的顺序保存
    2.确定缓冲区给自己的数据一定是大端,如果自己是大端,直接接受;如果是小端将大端的数据转为小端。
  • 因此,网络数据流的地址应该规定:先发的数据是低地址,后发的数据是高地址

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

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

1. htonl
   h表示host(主机),n表示network(网络),l表示long(32为长整数)
   其他的函数类似,s表示short16位短整数)
2. htons
   表示:将short(16位短整数)从主机字节序转为网络字节序
   eg:将ip地址转换后准备发送
3. 主机大端:函数不做转换,将参数原封不动返回
   主机小端:函数做大小端的相应转换,然后返回