Linux 系统编程 学习:06-基于socket的网络编程1:有关概念

Linux 系统编程 学习:006-基于socket的网络编程1:有关概念

背景

上一讲 进程间通信:System V IPC(2)中,我们介绍了System IPC中关于信号量的概念,以及如何使用。

这一讲我们来讨论"BSD socket(简称socket)",作为Linux中进程间通信的最后一种方式。实际上,socket可以跨主机通信。

本来文章标题应该以"进程间xxx"为字眼的,但是在开发中,我们更多提及"基于socket的网络编程"

知识

一开始学习网络编程的时候,看到 socket(套接字) 这个概念比较困扰。但后来通过搜索 以及在 结合在似懂非懂的开发中,最终弄懂了套接字的含义:

套接字是一种抽象的接口,我们不需要关心网络通信的具体细节,就可以将数据通过这种"端口"发生到我们希望送达的地方。

有关概念

端口号概念

在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型。

  • 物理端口指的是物理存在的端口,如ADSL Modem、集线器、交换机、路由器上用于连接其他网络设备的接口,如RJ-45端口、SC端口等等。
  • 逻辑端口是指逻辑意义上用于区分服务的端口,如TCP/IP协议中的服务端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等。

端口号使用:
TCP与UDP段结构中端口地址都是16比特,可以有在0 ~ 65535范围内的端口号。对于这65536个端口号有以下的使用规定:

  • 端口号小于256的定义为常用端口,服务器一般都是通过常用端口号来识别的。任何TCP/IP实现所提供的服务都用1 ~ 1023之间的端口号,是由ICANN来管理的;
  • 客户端只需保证该端口号在本机上是唯一的就可以了。客户端口号因存在时间很短暂又称临时端口号;
  • 大多数TCP/IP实现给临时端口号分配 1024 ~ 5000之间的端口号。大于5000的端口号是为其他服务器预留的。

TCP UDP

TCP(即传输控制协议)是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)

适用情况:

  • 适合于对传输质量要求较高,以及传输大量数据的通信。
  • 在需要可靠数据传输的场合,通常使用TCP协议
  • MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议

UDP(User Datagram Protocol)用户数据报协议
是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

适用情况:

  • 发送小尺寸数据(如对DNS服务器进行IP地址查询时)
  • 在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
  • 适合于广播/组播式通信中。
  • MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
  • 流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输

IP 地址 与 子网掩码

IP地址:Internet中主机的标识,Internet中的主机要与别的机器通信必须具有一个IP地址
IP地址为32位(IPv4)或者128位(IPv6);每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由。

表示形式:常用点分十进制形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。

IP地址分类:根据网络规模可以分为,A类,B类,C类,D类和E类。其中A、B、C是基本类,D、E类作为多播和保留使用。

子网掩码::(subnet mask)又叫网络掩码、地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。

字节序

不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO, Host Byte Order):

  • 小端序(little-endian):将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;
  • 大端序(big-endian):将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用。

为了避免不同类别主机之间在数据交换时由于对于字节序的不同而导致的差错,引入了网络字节序。网络中传输的数据必须按网络字节序,即大端字节序

在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成主机字节序(系统所采用的字节序)

在后面我们会用到一些转换函数。

// 主机字节序到网络字节序
u_long htonl (u_long hostlong);
u_short htons (u_short short);

// 网络字节序到主机字节序
u_long ntohl (u_long hostlong);
u_short ntohs (u_short short);

补充知识 :Socket 处在网络层次中的哪个位置?

虽然我对于套接字有自己的体会,但是我们可以结合OSI网络模型来加深我们的理解。

套接字(socket)编程接口是从顶上三层(网络协议的应用层)进入传输层的接口。除了提到的原始套接字,套接字编程可以彻底绕过IP层直接读写数据链路层的帧。

为什么套接字提供的是从OSI模型的顶上三层进入传输层的接口,有两个原因:

  • 顶上三层处理具体网络应用(如FTP、HTTP)的所有细节,而对通信细节了解很少;低下四层对具体网络应用了解不多,却处理所有的通信细节(发送数据、等待确认、校验等)。
  • 顶上三层通常构成所谓的用户进程,底下四层却通常作为操作系统内核的一个部分提供。现代操作系统都提供分隔用户进程与内核的机制。

所以,在第4层和第5层之间的接口是构建API的自然位置。

补充:Windows下的socket开发与Linux有何区别?

Windows下的socket程序开发和Linux思路相同,细节处区别如下:
1)Windows下的socket程序依赖Winsock.dll或ws2_32.dll,必须提前加载。
2)Linux使用“文件描述符”的概念,而Windows使用“文件句柄”的概念;Linux不区分socket文件和普通文件,而Windows区分;Linux下socket()函数的返回值为int类型,而Windows下为SOCKET类型,也就是句柄。
3)Linux下使用read()/write()函数读写,而Windows下使用recv()/send()函数发送和接收
4)关闭socket时,Linux使用close()函数,而Windows使用closesocket()函数。

posted @ 2019-03-20 18:20  schips  阅读(391)  评论(0编辑  收藏  举报