IP地址
Posted the-explosion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IP地址相关的知识,希望对你有一定的参考价值。
1、套接字概述
1.1、套接字定义
套接字最早是由BSD(伯克利软件套件)在1982年引入的通信机制,目前已被广泛移植到主流的操作系统中。
对于应用开发人员来说,套接字(socket)是一个抽象层,是一种特殊的I/O接口,也是一种文件描述符。应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。
Socket是一种常用的进程之间通信机制,不仅能实现本地不同进程之间的通信,而且通过网络能够在不同主机的进程之间进行通信。
套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
对于网络通信而言,每一个socket都可用网络地址结构{协议、本地地址、本地端口}来表示。Socket通过一个专门的函数创建,并返回一个整形的socket描述符。随后各种操作都是通过socket描述符来实现的。
套接字就是:一台主机的IP地址和端口号,套接字对就是互传信息两台主机的IP和端口号。在两台主机connect时,就是通过对应的套接字联系起来的。
对客户来说:需要明确自己要连接的服务器IP和端口号,而自己的IP和端口号一般由内核默认了,会在连接后传给服务器。
对服务器来说:需要明确自己监听的本机的端口就行,本机的IP可由宏INADDR_ANY经转换得到默认的IP给套接字结构。至于来自客户的IP和端口可以不用管,接收任何主机的连接。
1.2、简述
TCP/IP模型中的传输层实现端到端的通信,因此,每一个传输层连接有两个端点。那么,传输层连接的端点是什么呢?不是主机,不是主机的IP地址,不是应用进程,也不是传输层的协议端口。传输层连接的端点叫做套接字(socket)。根据RFC793的定义:端口号拼接到IP地址就构成了套接字。所谓套接字,实际上是一个通信端点,每个套接字都有一个套接字序号,包括主机的IP地址与一个16位的主机端口号,即形如(主机IP地址:端口号)。例如,如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)。
总之,套接字Socket =(IP地址:端口号),套接字的表示方法是点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。
套接字可以看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。因此,两个应用程序之间的数据传输要通过套接字来完成。
在网络应用程序设计时,由于TCP/IP的核心内容被封装在操作系统中,如果应用程序要使用TCP/IP,可以通过系统提供的TCP/IP的编程接口来实现。在Windows环境下,网络应用程序编程接口称作Windows Socket。为了支持用户开发面向应用的通信程序,大部分系统都提供了一组基于TCP或者UDP的应用程序编程接口(API),该接口通常以一组函数的形式出现,也称为套接字(Socket)。
1.3、发展
Socket最初是加利福尼亚大学Berkeley分校为Unix系统开发的网络通信接口。后来随着TCP/IP网络的发展,Socket成为最为通用的应用程序接口,也是在Internet上进行应用开发最为通用的API。
Windows系统流行起来之后,由Microsoft联合了其他几家公司在Berkeley Sockets的基础之上进行了扩充(主要是增加了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制),共同制定了一套Windows下的网络编程接口,即Windows Sockets规范。Windows Sockets规范是一套开放的、支持多种协议的Windows下的网络编程接口,包括1.1版和2.0版两个版本。其中1.1版只支持TCP/IP协议,而2.0版可以支持多协议,2.0版有良好的向后兼容性。当前Windows下的Internet软件绝大部分都是基于Windows Socks开发的
1.4、套接字类型
为了满足不同的通信程序对通信质量和性能的要求,一般的网络系统提供了三种不同类型的套接字,以供用户在设计网络应用程序时根据不同的要求来选择。这三种套接为流式套接字(SOCK-STREAM)、数据报套接字(SOCK-DGRAM)和原始套接字(SOCK-RAW)。
(1)、流式套接字(SOCK_STREAM)
它提供了一种可靠的、面向连接的双向数据传输服务,实现了数据无差错、无重复的发送,保证数据传输的可靠性和按序收发。流式套接字内设流量控制,被传输的数据看作是无记录边界的字节流。在TCP/IP协议簇中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
(2)、数据报套接字(SOCK_DGRAM)
它提供了一种无连接、不可靠的双向数据传输服务。数据通过相互独立的报文进行传输,是无序的,并且保留了记录边界,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在TCP/IP协议簇中,使用UDP协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。
(3)、原始套接字(SOCK_RAM)
该套接字允许对较低层协议(如IP或ICMP)进行直接访问,它功能强大使用较为不便,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。
2、IP地址和端口号
2.1、IP地址的作用
IP地址用来标识网络中的一台主机。根据不同的协议版本,分为IPv4(32位)和IPv6(128位)。
一个IP地址主要包含两部分:网络号和主机号。其中,网络号和主机号根据子网掩码来区分。简单的说,有了源IP和目标IP,数据包就能在不同的主机之间传输。
2.2、IP地址格式转换
IP地址有两种不同的格式:十进制点分形式和32位二进制形式。前者是用户所熟悉的形式,而后者则是网络传输中IP地址的存储方式。
IPv4地址转换函数有inet_addr()、inet_aton()、inet_ntoa(),而IPv4和IPv6兼容的函数有inet_pton()和inet_ntop()。由于IPv6是下一代互联网的标准协议,因此这里讲解主要以IPv4为主。
inet_addr()和inet_pton()函数是将十进制点分形式转换成二进制形式,而inet_ntop()是将二进制地址形式转换为十进制点分形式。
头文件 |
#include <arpa/inet.h> |
|
函数原型 |
int inet_addr(const char *strptr); |
|
作用 |
将十进制转换成二进制,适用于IPv4 |
|
参数 |
Strptr |
要转换的IP地址字符串 |
返回值 |
成功 |
32位二进制IP地址(网络字节序) |
失败 |
-1 |
头文件 |
#include <arpa/inet.h> |
|
函数原型 |
int inet_pton(int family,const char *src,void *dst); |
|
作用 |
将十进制转换成二进制,IPv4和IPv6兼容 |
|
参数 |
family |
AF_INET:IPv4 |
AF_INET6:IPv6 |
||
src |
要转换的IP地址字符串 |
|
dst |
存放转换后的地址的缓冲区 |
|
返回值 |
成功 |
0 |
失败 |
-1 |
头文件 |
#include <arpa/inet.h> |
|
函数原型 |
int inet_ntop(int family,void *src,char *dst,size_t len); |
|
作用 |
将二进制转换成十进制,IPv4和IPv6兼容 |
|
参数 |
family |
AF_INET:IPv4 |
AF_INET6:IPv6 |
||
src |
要转换的二进制IP地址 |
|
dst |
存放十进制地址字符串的缓冲区 |
|
len |
缓冲区的长度 |
|
返回值 |
成功 |
返回dst |
失败 |
NULL |
2.3、地址数据结构体
1 struct sockaddr 2 { 3 unsigned short sa_family; /*地址族*/ 4 char sa_data[14]; /*14字节的协议地址*/ 5 } 6 7 struct sockaddr_in 8 { 9 short int sin_family; /*地址族*/ 10 struct in_addr sin_addr; /*IP地址*/ 11 unsigned short int sin_port; /*端口号*/ 12 unsigned char sin_zero[8]; /*填充0 以保持与struct sockaddr同样大小*/ 13 } 14 15 struct in_addr 16 { 17 in_addr_t s_addr; /*IP地址 ,in_addr_t一般为32位的unsigned int,其字节顺序为网络字节序,即该无符号数采用大端字节序*/ 18 }
这两个数据类型大小相同,通常用sockaddr_in来保存某个网络地址,在使用时强转成sockaddr类型的指针。
结构定义头文件 |
#include <netinet/in.h> |
sa_family
|
AF_INET:IPv4协议 |
AF_INET6:IPv6协议 |
|
AF_LOCAL:UNIX域协议 |
|
AF_LINK:链路地址协议 |
|
AF_KEY:密钥套接字 |
|
AF_INET:IPv4协议 |
2.4、端口号
端口号是一个无符号短整形(unsigned short int),取值范围0到65535。端口号是系统的一种资源,0~1023一般被系统程序所使用。TCP端口号和UDP端口号独立,互不影响。
如果说IP地址可以用来表示网络中的一台主机,那么端口号可以用来表示主机内部的某个套接字。换句话说,当一个套接字创建好后,需要把它和某个IP地址及端口号绑定,这样双方才能实现端到端通信。
3、字节序
字节序又称为主机字节序,是指计算机中多字节整形数据的存储方式。字节序有两种:大端(低地址存高位字节,高地址存低位字节)和小端(低字节存低位字节,高地址存高位字节),在网络通信中,发送方和接收方有可能使用不同的字节序,为了保证数据接收后能正确的解析处理,统一规定:数据以高字节优先顺序在网络上传输。因此数据在发送前和接收后都需要在主机字节序和网络字节序之间转换。
3.1、函数说明
字节序转换涉及4个函数:htons()、ntohs()、htonl()和ntohl()。这里的h代表host,n代表network,s代表short,l代表long,l代表long。通常16bit的IP端口号用前两个函数处理,而IP地址用后两个函数来转换。调用这些函数只是使其得到相应的字节序,用户不需要知道该系统的主机字节序和网络字节序是否真正相等。如果相同不需要转换的话,该系统的这些函数会定义成空宏。
3.2、函数格式
头文件 |
#include <netinet/in.h> |
|
函数原型 |
Uint16_t htons(uint16_t hostshort) Uint32_t htonl(uint16_t hostlong) Uint16_t ntohs(uint16_t netshort) Uint32_t ntohl(uint16_t netlong) |
|
参数 |
hostshort |
主机字节序的16bit数据 |
hostlong |
主机字节序的32bit数据 |
|
netshort |
网络字节序的16bit数据 |
|
netlong |
网络字节序的32bit数据 |
|
返回值 |
成功 |
返回转换字节序后的数值 |
失败 |
-1 |
以上是关于IP地址的主要内容,如果未能解决你的问题,请参考以下文章