uc_14_IP地址_套接字_字节序转换
1? 计算机网络
? ? ? ? 计算机网络,是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
? ? ? ? 网络协议是一种特殊的软件,是计算机网络实现其功能的最基本的机制。网络协议的本质就是规则,即各种硬件和软件必须遵循的共同守则。网络协议并不是一套单独的软件,它融合于其他所有的软件甚至硬件系统中,因此可以说协议在网络中无所不在。
? ? ? ? 为了减少网络设计的复杂性,绝大多数网络采用分层设计的方法。所谓分层设计,就是按照信息的流动过程将网络的整体功能分解为一个个的功能层,不同机器上的同等功能层之间采用相同的协议,同一机器上的相邻功能层之间通过接口进行信息传递。各层的协议和结构统称为协议栈。
? ? ? ? 描述计算机网络各协议层的一般方法是采用国际标准化组织(International Standardization Organization)的计算机通信开放系统互联(Open System Interconnection)模型,简称ISO/OSI网络协议模型:
????????
????????
TCP/IP:
????????TCP/IP不是个单一的网络协议,而是由一组具有层次关系的网络协议组成的协议家族,简称TCP/IP协议族:
? ? ? ? TCP:传输控制协议,面向连接,可靠的全双工的字节流
? ? ? ? UDP:用户数据报协议,无连接,不如TCP可靠但速度快
? ? ? ? ICMP:网际控制消息协议,处理路由器和主机间的错误和控制消息
? ? ? ? IGMP:网际组管理协议,用于多播
? ? ? ? IPv4:网际协议版本4,使用32位地址,为TCP、UDP、ICMP、IGMP提供递送分组服务
? ? ? ? IPv6:网际协议版本6,使用128位地址,为TCP、UDP、ICMPv6提供递送分组服务
? ? ? ? ARP:地址解析协议,把IPv4地址映射到硬件地址
? ? ? ? RARP:逆地址解析协议,把硬件地址映射到IPv4地址
? ? ? ? ICMPv6:网际控制消息协议版本6,总和了ICMP、IGMP、ARP的功能
? ? ? ? BPF:BSD分组过滤器,为应用程序提供访问数据链路层的接口,由源自BSD的系统内核
? ? ? ? ? ? ? ? ? ?提供
? ? ? ? DLPI:数据链路提供者接口,为应用程序提供访问数据链路层的接口,由源自SVR4的系统
? ? ? ? ? ? ? ? ? ? 内核提供
????????
? ? ? ? 在ISO/OSI网络协议模型的基础上,TCP/IP协议做了部分合并和简化,同时将网络编程的接口设定在传输层与会话层之间,这样做的理由有二:
? ? ? ? 1)上三层与应用程序的业务逻辑(如数据包的组织与解析、收发的时机与次序等)密切相关,而与具体的通信细节(如收发分组、等待确认、分组排序、计算验证校验、丢包重传等)关系不大;下四层主要处理通信细节而与具体应用的业务逻辑无关。
? ? ? ? 2)上三层通常构成用户进程,而下四层通常是系统内核的一部分。
????????
消息包和消息流:
? ? ? ? 应用程序负责组织的通常都是与业务相关的数据内容,而要想把这些数据内容通过网络发送出去,就要将其自上而下地压入协议栈,每经历一个协议层,就会对数据做一层封包,每一层输出的封包都是下一层输入的内容,消息包沿着协议栈的运动形成了消息流。
? ? ? ? 当从网络上接收数据时,过程刚好相反,消息包自下而上地流经协议栈,每经历一个协议层,就会对输入的数据解一层封包,经过层层解包以后,应用程序最终得到的将只是与业务相关的数据内容。数据的封装和解析过程:
????????
2? IP地址
? ? ? ? IP地址,全称网际协议地址(Internet Protocol Address),是IP协议提供的一种统一的地址格式,为互联网上的每个网络和每台主机分配一个逻辑地址,借以消除物理地址差异性所带来的影响。
????????百度查到是公网IP:106.222.188.106? ?,包含若干私网IP
????????ifconfig查是私网IP:192.168.221.68
? ? ? ? 在计算机内部,IP地址用一个32位的无符号整数表示,如:0x01020304
? ? ? ? 人们更习惯使用点分十进制字符串表示,如:1.2.3.4。字符串形式的从左到右,对应整数形式的高字节到低字节。注意这里所说的高低指的是数位高低而非地址高低。
? ? ? ? IP地址分级:
? ? ? ? A级地址:以0为首的8位网络地址? ? ? ? +24位本地地址
? ? ? ? B级地址:以10为首的16位网络地址? ? +16位本地地址
? ? ? ? C级地址:以110为首的24为网络地址? +8位本地地址
? ? ? ? D级地址:以1110为首的32位多播地址
? ? ? ? 如某计算机的IP地址:192.168.182.48是C级地址,网络地址192.168.182.0,本地地址48。
? ? ? ? 借助子网掩码可以快速帮我们确定IP地址的网络地址和本地地址:
? ? ? ? 网络地址 = IP地址 & 子网掩码
? ? ? ? ? ? ? ? ? ? ? ? ? 192.168.182.48 & 255.255.255.0 = 192.168.182.0
? ? ? ? 本地地址 = IP地址 & ~子网掩码
? ? ? ? ? ? ? ? ? ? ? ? ? 192.168.182.48 & 0.0.0.255 = 0.0.0.48
3? 套接字socket
3.0? 理论
????????套接字(socket)本意是电源插座,这里将其引申为一个基于TCP/IP协议可实现基本网络通信功能的逻辑对象。
? ? ? ? 机器与机器的通信,或者进程与进程的通信,在这里都可以被抽象地看作是套接字与套接字的通信。
? ? ? ? 应用程序编写者无需了解网络协议的任何细节,更无需知晓系统内核和网络设别的运作机制,只要把想发送的数据写入套接字,或从套接字中读取想接收的数据即可。
????????
? ? ? ? 从这个意义上讲,套接字就相当于一个文件描述符,而网络就是一种特殊的文件,面向网络的编程与面向文件的编程已没有分别,而这恰恰是Unix系统一切皆文件思想的又一例证。?
? ? ? ? 套接字是对ISO/OSI网络协议模型中传输层及其以下诸层的逻辑抽象,是对TCP/IP网络通信协议的高级封装,因此无论所依赖的是什么硬件,所运行的什么操作系统,所使用的是什么编程语言,只要是基于套接字构建的应用程序,只要是在互联网环境中通信,就不会存在任何障碍。
? ? ? ? 如前所述,套接字是一个提供给程序员使用的逻辑对象,它表示对ISO/OSI网络协议模型中传输层及其以下诸层的抽象。但真正发送和接收数据的毕竟是大写实实在在的物理设备。这就需要在物理设备和逻辑对象之间建立一种关联,使后续所有针对这个逻辑对象的操作,最终都能够反映到实际的物理设备上。建立这种关联关系的过程就叫做绑定:
????????
? ? ? ? 绑定只是把套接字对象和一个代表自己的物理设备关联起来。为了实现通信还需要把自己的物理设备与对方的物理设备关联起来。只有这样才能建立起一种物理设备为媒介的,跨越不同进程甚至机器的,多个套接字对象之间的联系。建立这种联系的过程叫做连接:
????????
?3.1? socket()
? ? ? ? #include <sys/socket.h>
? ? ? ? int socket ( int domain,? int type,? int protocol );
? ? ? ? ? ? ? ? 功能:创建套接字
? ? ? ? ? ? ? ? domain:通信域,协议族,可取以下值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_LOCAL / PF_UNIX? ? ? ? 本地套接字,进程间通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_INET? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于IPv4的网络通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_INET6? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于IPv6的网络通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_PACKET? ? ? ? ? ? ? ? ? ? ? ? 基于底层包的网络通信?
? ? ? ? ? ? ? ? type:套接字类型,可取以下值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_STREAM? ? ? ? ? ? ? ? 流式套接字,基于TCP协议
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_DGRAM? ? ? ? ? ? ? ? ? 数据报套接字,基于UDP协议
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_RAW? ? ? ? ? ? ? ? ? ? ? ?原始套接字,工作在传输层以下
? ? ? ? ? ? ? ? protocol:特殊协议,对于流式和数据报套接字而言,只能取0
? ? ? ? ????????返回值:成功返回表示套接字对象的文件描述符,失败返回-1?
? ? ? ? 套接字接口库通过地址结构定位一个通信主体,可以是一个文件,可以是一台远程主机,也可以是执行者自己:
? ? ? ? -基本地址结构,本身没有实际意义,仅用于泛型化参数
? ? ? ????????????????? struct? sockaddr {
? ? ? ? ? ? ????????????????? ? sa_family_t? ?sa_family;? ????????// 地址族
? ? ? ? ? ? ????????????????? ? char? ? ? ? ? ? ? sa_data[14];? ? ? ?// 地址值
? ? ? ????????????????? };
? ? ? ? -本地地址结构,用于AF_LOCAL/AF_UNIX域的本地通信
? ? ? ?????????????????struct? sockaddr_un {
? ? ? ? ? ? ????????????????? ? sa_family_t? ?sun_family;? // 地址族(AF_LOCAL/AF_UNIX)
? ? ? ? ? ? ????????????????? ? char? ? ? ? ? ? ? sun_path[];? ?// 本地套接字文件的路径
? ? ? ????????????????? }
? ? ? ? -网络地址结构,用于AF_INET域的IPv4网络通信
????????????????????????struct? sockaddr_in {
? ? ? ? ? ? ????????????????? ? sa_family_t? ? ? ? ? sin_family;? // 地址族(AF_INET)
? ? ? ? ? ? ? ? ????????????????in_port_t? ? ? ? ? ? ? sin_port;? ? ?//? 端口号(0~65535) -unsigned short
? ? ? ? ? ? ? ? ????????????????struct? in_addr? ? ?sin_addr;? ? // IP地址 -unsigned int
? ? ? ? ????????????????}????????
? ? ? ? -网络地址结构,用于AF_INET域的IPv4网络通信
? ? ? ? ? ? ? ? ? ? ? ? struct? in_addr {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_addr_t? s_addr;
? ? ? ? ? ? ? ? ? ? ? ? }
????????????????????????typedef? ?uint16_t? ?in_port_t;? // 无符号16位正数
? ? ? ? ? ? ? ? ? ? ? ? typedef? ?unit32_t? ?in_addr_t; // 无符号32位正数
? ? ? ? 如前所述,通过IP地址可以定位网络上的一台主机,但一台主机上可能同时有多个网络应用在运行,究竟想跟哪个网络应用通信呢?这就需要靠端口号来区分,因为不同的网络应用会使用不同的端口号。用IP地址定位主机,再用端口号定位运行在这台主机上一个具体的网络应用,这样一种对通信主体的描述才是唯一确定的。
? ? ? ? 套接字接口库中的端口号被定义为一个16位的无符号整数,0~65535,其中0~1024已被系统和一些网络服务占据:
? ? ? ? 21端口? ? ? ? ftp服务
? ? ? ? 23端口? ? ? ? telnet服务
? ? ? ? 89端口? ? ? ? www服务
? ? ? ? 3306端口? ? 数据库服务器
? ? ? ? 因此一般程序最好选择1024以上的端口号,以避免和这些服务冲突。
3.2? bind()
? ? ? ? #include <sys/socket.h>
? ? ? ? int? bind ( int sockfd,? struct sockaddr const* addr,? socklen_t addrlen );
? ? ? ? ? ? ? ? 功能:将套接字和本地的地址结构绑定在一起
? ? ? ? ? ? ? ? sockfd:套接字描述符
? ? ? ? ? ? ? ? addr:自己的地址结构
? ? ? ? ? ? ? ? addrlen:地址结构的字节数
? ? ? ? ? ? ? ? 返回值:成0败-1?
3.3? connect()
? ? ? ? #include <sys/socket.h>
? ? ? ? int? connect ( int sockfd,? ?struct sockaddr const* addr,? ?socklen_t addrlen );
? ? ? ? ? ? ? ? 功能:将套接字和对方的地址结构连接在一起
? ? ? ? ? ? ? ? sockfd:套接字描述符
? ? ? ? ? ? ? ? addr:对方的地址结构
? ? ? ? ? ? ? ? addrlen:地址结构的字节数
? ? ? ? ? ? ? ? 返回值:成0败-1?
4? 字节序转换
? ? ? ? 网络应用与单击应用不同,经常需要在具有不同硬件架构和操作系统的计算机之间交换数据,因此编程语言里一些多字节数据类型的字节序问题就特别予以关注。
? ? ? ? 套接字接口库规定在网络传输过程中采用网络字节序,也就是大端字节序,而本机数据可能是小端字节序。
? ? ? ? 主机:小端字节序:数据的低位存放在低地址
????????????????
?
? ? ? ? 网络:大端字节序:数据的低位存放在高地址
????????????????
转换函数:
? ? ? ? uint32_t? ?htonl ( uint32_t hostlong );? // 长整型? 主机字节序? 到? 网络字节序
? ? ? ? uint32_t? ?ntohl ( uint32_t netlong );? ? // 长整型? 网络字节序? 到? 主机字节序
? ? ? ? uint16_t? ?htons ( uint16_t hostshort );? // 短整型? 主机字节序? 到? 网络字节序
? ? ? ? uint16_t? ?ntohs ( uint16_t netshort?);? ? // 短整型? 网络字节序? 到? 主机字节序
????????
? ? ? ? in_addr_t? ?inet_addr ( char const* ip ); // 点分十进制字符串地址?到 网络字节序形式整数地址
? ? ? ? int? ?inet_aton ( char const* ip,? ?struct in_addr* nip );
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 点分十进制字符串地址 到 网络字节序形式整数地址
? ? ? ? char*? ?inet_ntoa ( struct in_addr nip ); // 网络字节序形式整数地址 到 点分十进制字符串地址
相关代码 结合 uc_15
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!