TCP.IP网络字节顺序转换函数htonl-ntohl-htons-ntohs
htonl(),htons(),ntohl(),ntons()--大小端模式转换函数
htonl(),htons(),ntohl(),ntons()--大小端模式转换函数不同机器内部对变量的字节存储顺序不同,有的采用大端模式(big-endian),有的采用小端模式(little-endian)。
大端模式是指高字节数据存放在低地址处,低字节数据放在高地址处。
小端模式是指低字节数据存放在低地址处,高字节数据放在高地址处。
在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此TCP/IP 协议规定了在网络上必须采用网络字节顺序(也就是大端模式)。
通过对大小端的存储原理分析可发现,对于char 型数据,由于其只占一个字节,所以不存在这个问题,这也是一般情况下把数据缓冲区定义成char 类型的原因之一。
对于IP 地址、端口号等非char 型数据,必须在数据发送到网络上之前将其转换成大端模式,在接收到数据之后再将其转换成符合接收端主机的存储模式。
Linux 系统为大小端模式的转换提供了4 个函数,输入man byteorder命令可得函数原型:1.#include <arpa/inet.h>2.3.uint32_t htonl(uint32_t hostlong);4.5.uint16_t htons(uint16_t hostshort);6.7.uint32_t ntohl(uint32_t netlong);8.9.uint16_t ntohs(uint16_t netshort);#include <arpa/inet.h>uint32_thtonl(uint32_t hostlong);uint16_thtons(uint16_t hostshort);uint32_tntohl(uint32_t netlong);uint16_tntohs(uint16_t netshort);htonl表示host to network long ,用于将主机unsigned int型数据转换成网络字节顺序;htons表示host to network short ,用于将主机unsigned short 型数据转换成网络字节顺序;ntohl、ntohs的功能分别与htonl、htons相反。
网络字节序列及转化函数
网络字节序列及转化函数1. 网络字节序列网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。
2. 网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)htons 把unsigned short类型从主机序转换到网络序htonl 把unsigned long类型从主机序转换到网络序ntohs 把unsigned short类型从网络序转换到主机序ntohl 把unsigned long类型从网络序转换到主机序3.常用转化函数inet_aton()inet_aton() 是将一个字符串IP地址转换为一个32位的网络序列IP地址。
函数概要说明:头文件:#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>完整描述:int inet_aton(const char *string, struct in_addr*addr);参数描述:1 输入参数string包含ASCII表示的IP地址。
2 输出参数addr是将要用的新的IP地址结构。
返回值:如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零。
4. Linux下,将IP地址在“点分十进制”和“整数”之间转换inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。
1) inet_pton函数原型如下: [将“点分十进制” -> “整数”]#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>int inet_pton(int af, const char *src, void *dst);这个函数转换字符串到网络地址,第一个参数af是地址族,第二个参数*src是来源地址,第三个参数* dst接收转换后的数据。
打造自己的字节序转换函数(16位、32位和64位)
打造自己的字节序转换函数(16位、32位和64位)在计算机科学领域中,字节序是指存放多字节数据的字节(byte)的顺序,典型的情况是整数在内存中的存放方式和网络传输的传输顺序。
不同的处理器所采用的字节序可能是不同的,例如:x86,6502, Z80, VAX,和PDP-11都是采用小端字节序,而 Motorola 6800、68k, IBM POWER, 和System/360则采用大端字节序。
另外,网络协议通常也会规定其所采用的字节序,还有像java 这样的语言,也是规定了字节序的(tcp/ip和java都是采用大端字节序)。
通常,系统中会提供ntohs、htons、ntohl、htonl这4个函数,已实现16位和32位本地字节序和网络字节序的转换。
但是,目前好像还没有提供64位数据字节序的转换函数。
所以,在这里自己动手写一个。
首先,我们要判断本地系统所采用的字节序:[cpp]view plaincopy1.#define BigEndian 12.#define LittleEndian 03.static bool BigEndianTest()4.{5./*定义一个2个字节长度的数据,并赋值为1,则n的16进制表示为0x00016.如果系统以“大端”存放数据,也即是以MSB方式存放,那么低字节存放的必定是0x00,高字节存放的必定是0x017.如果系统以“小端”存放数据,也即是以LSB方式存放,那么低字节存放的必定是0x01,高字节存放的必定是0x008.所谓MSB,就是将最重要的位存入低位,而LSB则是将最不重要的位存入低位9.我们可以通过检测低位的数值就可以知道系统的字节序10.*/11.const __int16 n = 1;12.if(*(char *)&n)13.{14.return LittleEndian;15.}16.return BigEndian;17.}当然这里可以再优化一下,写成宏定义。
TCP-IP详解学习笔记
TCP-IP详解学习笔记TCP/IP详解学习笔记基本概念为什么会有TCP/IP协议在世界上各地,各种各样的电脑运⾏着各⾃不同的操作系统为⼤家服务,这些电脑在表达同⼀种信息的时候所使⽤的⽅法是千差万别。
就好像圣经中上帝打乱了各地⼈的⼝⾳,让他们⽆法合作⼀样。
计算机使⽤者意识到,计算机只是单兵作战并不会发挥太⼤的作⽤。
只有把它们联合起来,电脑才会发挥出它最⼤的潜⼒。
于是⼈们就想⽅设法的⽤电线把电脑连接到了⼀起。
但是简单的连到⼀起是远远不够的,就好像语⾔不同的两个⼈互相见了⾯,完全不能交流信息。
因⽽他们需要定义⼀些共通的东西来进⾏交流,TCP/IP就是为此⽽⽣。
TCP/IP不是⼀个协议,⽽是⼀个协议族的统称。
⾥⾯包括了IP协议,IMCP协议,TCP协议,以及我们更加熟悉的http、ftp、pop3协议等等。
电脑有了这些,就好像学会了外语⼀样,就可以和其他的计算机终端做⾃由的交流了。
TCP/IP协议分层提到协议分层,我们很容易联想到ISO-OSI的七层协议经典架构,但是TCP/IP协议族的结构则稍有不同。
如图所⽰TCP/IP协议族按照层次由上到下,层层包装。
最上⾯的就是应⽤层了,这⾥⾯有http,ftp,等等我们熟悉的协议。
⽽第⼆层则是传输层,著名的TCP和UDP协议就在这个层次(不要告诉我你没⽤过udp玩星际)。
第三层是⽹络层,IP协议就在这⾥,它负责对数据加上IP 地址和其他的数据(后⾯会讲到)以确定传输的⽬标。
第四层是叫数据链路层,这个层次为待传送的数据加⼊⼀个以太⽹协议头,并进⾏CRC编码,为最后的数据传输做准备。
再往下则是硬件层次了,负责⽹络的传输,这个层次的定义包括⽹线的制式,⽹卡的定义等等(这些我们就不⽤关⼼了,我们也不做⽹卡),所以有些书并不把这个层次放在tcp/ip协议族⾥⾯,因为它⼏乎和tcp/ip协议的编写者没有任何的关系。
发送协议的主机从上⾃下将数据按照协议封装,⽽接收数据的主机则按照协议从得到的数据包解开,最后拿到需要的数据。
大头小头字节序网络字节序与主机字节序
大头小头字节序:网络字节序与主机字节序不同的CPU有不同的字节序类型这些字节序是指整数在内存中保存的顺序这个叫做主机序最常见的有两种1.Little endian(小头):将低序字节存储在起始地址2.Big endian(大头):将高序字节存储在起始地地址LE little-endian最符合人的思维的字节序地址低位存储值的低位地址高位存储值的高位怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位反之,高位值就应该放在内存地址大的地方,也即内存地址高位BE big-endian最直观的字节序地址低位存储值的高位地址高位存储值的低位为什么说直观,不要考虑对应关系只需要把内存地址从左到右按照由低到高的顺序写出把值按照通常的高位到低位的顺序写出两者对照,一个字节一个字节的填充进去例子:在内存中双字0x01020304(DWORD)的存储方式内存地址4000 4001 4002 4003LE 04 03 02 01BE 01 02 03 04例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为big-endian little-endian0x00000x12 0xcd0x00010x23 0xab0x00020xab 0x340x00030xcd 0x12x86系列C P U都是l ittle-endian的字节序.网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的C PU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。
网络字节顺序采用big endian排序方式。
为了进行转换bsd socket提供了转换的函数有下面四个htons把unsig ned short类型从主机序转换到网络序htonl把unsig ned long类型从主机序转换到网络序ntohs把unsig ned short类型从网络序转换到主机序ntohl把unsig ned long类型从网络序转换到主机序在使用lit tle endian的系统中这些函数会把字节序进行转换在使用big endian类型的系统中这些函数会定义成空宏同样在网络程序开发时或是跨平台开发时也应该注意保证只用一种字节序不然两方的解释不一样就会产生bu g.注:1、网络与主机字节转换函数:htonsntohshtonl ntohl (s 就是short l是long h是host n是net w o rk)2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
字节序(endian)、字节序转换
java字节序转换参见java总结。
注意:IEEE 754标准只是规范了float、double的逻辑规范,其存储时还是会有字节序问题,
因此在不同系统或者编程语言之间进行传输数据时,也要考虑字节序问题。
程序(字节序平台无关的语言除外,如:java)。
c/c++/c#在windows上是小端字节序;java是大端字节序,与平台无关。
c/c++中字节序转换:
ntohs =net to host short int 16位
htons=host to net short int 16位
2015-3-29 08:44:15
=== 字节序(endian)
字节序分为主机字节序和网络字节序。主机字节序是指多于一个字节类型的数据在内存
或磁盘中的存放顺序。网络字节序是指多于一个字节类型的数据在传输时的字节顺序。
通常有小端(little-endian)、大端(big-endian)两种字节序。小端字节序指低字节
ntohl =net to host long int 32位
htonl=host to net long int 32位
c#中字节序转换:
主机字节序到网络字节序:short/int/long IPAddress.HostToNetworkOrder(short/int/long)
到目前为止,基本上你所见到的所有windows都是小端的,在可配置字节序的CPU上,
windows选择的是小端,以便更好的兼容程序。windows主机字节序不兼容大端字节序,
vs2015 字节序转换
vs2015 字节序转换一、大端字节序和小端字节序大端字节序:一个整数的高位字节(23~31bit)存储在内存的低地址处,低位字节(0~7bit)存储在内存的高地址处。
小端字节序:一个整数的高位字节(23~31bit)存储在内存的高地址处,低位字节(0~7bit)存储在内存的低地址处。
现代PC大多采用小端字节序,因此其又被称为主机字节序。
对应的,大端字节序也称为网络字节序。
二、字节序的转换/* 主机字节序到网络字节序的转换 */unsigned long int htonl(unsigned long int hostLong);unsigned short int htons(unsigned short int hostShort);/* 网络字节序到主机字节序的转换 */unsigned long int ntohl(unsigned long int netLong);unsigned short int ntohs(unsigned short int netShort);补:长整型函数通常用来转换IP地址,短整型函数用来转换端口号。
任何格式化的数据通过网络传输时,都应该使用这些函数来转换字节序。
三、余音绕梁1. 为何网络字节序是大端字节序?当格式化的数据在两台使用不同字节序的主机之间直接传递时,接收端必然错误地解释之。
提出的解决方法是:发送端总是把发送的数据转化成大端字节序数据(小端机转换,大端机不转换)后再发送,于是接收端知道对方传送过来的数据总是采用大端字节序,所以接收端可以根据自身采用的字节序决定是否对接收到的数据进行转换(小端机转换,大端机不转换)。
因此大端字节序也称为网络字节序。
2. 即使你的主机是大端机,最好也在收发数据时进行字节序转换这样写出来的代码可移植性更好这种情况下,字节序转换函数并不会修改数据的字节序3. 确定主机是大端机还是小端机void judge(){union {short s;char c[sizeof(short)];} un;un.s = 0x0102;// 短整数s的高位字节0x01放在内存的低地址处if(un.c[0] == 1 && un.c[1] == 2)printf("big endian\n");// 短整数s的高位字节0x01放在内存的高地址处 else if(un.c[0] == 2 && un.c[1] == 1)printf("little endian\n");elseprintf("unknown...\n");}。
ip转字符串函数
ip转字符串函数IP转字符串函数是一种常见的编程函数,用于将IP地址转换为字符串形式。
在网络编程和系统管理中,经常需要将IP地址以字符串的形式进行处理和展示。
下面将介绍一种常见的IP转字符串函数的实现方法。
首先,IP地址是由32位二进制数表示的,通常以四个十进制数的形式表示,每个数之间用点号分隔。
例如,IP地址"192.168.0.1"可以表示为32位二进制数"11000000 10101000 00000000 00000001"。
要实现IP转字符串函数,首先需要将IP地址表示为32位二进制数。
可以使用位运算来实现这一步骤。
假设IP地址的类型为unsigned int,可以使用以下代码将IP地址转换为32位二进制数:```c++unsigned int ipToBinary(unsigned int ip) {unsigned int binary = 0;binary |= (ip & 0xFF) << 24;binary |= (ip & 0xFF00) << 8;binary |= (ip & 0xFF0000) >> 8;binary |= (ip & 0xFF000000) >> 24;return binary;}```接下来,需要将32位二进制数转换为字符串形式。
可以使用字符串拼接的方式来实现这一步骤。
假设IP地址的类型为unsigned int,可以使用以下代码将32位二进制数转换为字符串:```c++std::string binaryToString(unsigned int binary) {std::string str;for (int i = 0; i < 4; i++) {unsigned int octet = (binary >> (8 * (3 - i))) & 0xFF;str += std::to_string(octet);if (i < 3) {str += ".";}}return str;}```最后,将上述两个函数结合起来,即可实现IP转字符串函数。
Windows网络编程复习重点
Windows⽹络编程复习重点⽬录第⼀章⽹络应⽤程序设计基础 (3)分布式⽹络应⽤程序的特点及分类 (3)⾯向应⽤的⽹络编程⽅法(3点) (3)基于TCP/IP的⽹络编程⽅法 (3)⾯向原始帧的⽹络编程⽅法(4种) (4)第⼆章⽹络程序通信模型 (4)常见的⽹络编程通信模型 (4)客户端、服务器的⼯作过程 (4)P2P模型的特点及其⽹络的拓扑结构 (5)第三章⽹络数据的内容与形态 (6)⽹络字节顺序与主机字节顺序 (6)⽹络字节顺序与主机字节顺序转换的函数 (6)⽹络数据传输形态 (6)字符编码 (7)数据校验 (7)第四章软件协议接⼝ (7)协议软件接⼝的位置与功能 (7)WinSock DLL的初始化与释放 (8)WinSock的地址描述 (9)套接字选项和IO控制命令 (9)处理WinSock的错误 (9)第五章流式套按字编程 (9)流式套接字通信的特点 (9)流式套接字的适⽤场景 (10)基本函数 (10)流式套接字编程的⼀般过程 (12)正确处理流数据的接收 (13)接收定长和变长数据 (13)流式套接字的编程实例 (13)第六章数据报套接字编程 (21)数据报套接字数据通信的特点 (21)数据报套接字的适⽤场景 (21)数据报套接字的编程的⼀般过程 (21)数据报套接字的常⽤函数 (22)数据报套接字的编程实例 (22)第七章原始套接字编程 (27)原始套接字的特点 (27)原始套接字的适⽤场景 (28)原始套按字的编程的⼀般过程 (28)原始套接字的编程实例 (28)第⼋章⽹络通信中的IO操作 (37)套接字的常见IO模式 (37)同步、异步、阻塞、⾮阻塞的概念及区别 (37)阻塞IO模型的⼯作原理与特点 (38)⾮阻塞IO模型的⼯作原理与特点 (38)IO复⽤模型的⼯作原理与特点(选择模型) (38)异步IO复⽤模型的⼯作原理与特点(WSAAsynsSelect) (38)完成端⼝模型的⼯作原理与特点(异步) (39)第九章WinPcap编程 (39)Wpcap.dll的⼯作流程 (39)Wpcap.dll的编程实例 (40)Packet.dll的⼯作流程 (45)Packet.dll编程实例 (45)第⼀章⽹络应⽤程序设计基础分布式⽹络应⽤程序的特点及分类1、特点:3点A)分布式⽹络应⽤程序将整个应⽤程序的处理分成⼏个部分,分别在不同的机器上运⾏,这⾥的“分布”包含两层含义:地理上的分布和数据处理的分布。
tcp ip工作原理
tcp ip工作原理TCP/IP是一种网络通信协议,它包括两个独立的协议:TCP (Transmission Control Protocol,传输控制协议)和IP (Internet Protocol,网际协议)。
TCP协议负责将应用层数据分割成小块,称为报文段(segment),并提供可靠的传输机制。
它通过使用序号和确认机制,确保数据按照正确的顺序传输到目标主机。
TCP使用三次握手(three-way handshake)进行连接建立,即发送方先发送一个连接请求报文段,接收方响应一个确认报文段,发送方再发送一个确认报文段,建立了双方之间的连接。
传输完成后,TCP还使用四次挥手(four-way handshake)进行连接的终止。
IP协议则负责将数据报从源主机发送到目标主机。
它使用IP地址标识主机和路由器,将数据报分割成小块(称为数据报),并选择合适的路径进行转发。
每个数据报都包含源IP地址和目标IP地址,以便于路由器可以找到正确的下一个跃点。
当发送方的应用程序需要向目标主机发送数据时,TCP将数据分割成适当大小的报文段,并将它们传递给IP层。
IP层将每个报文段封装在IP数据包中,并添加目标IP地址和源IP地址的头部信息。
这些IP数据包随着目标地址发送到网络中。
在网络中,路由器根据目标IP地址查找下一个跃点,并将IP数据包转发到下一个跃点。
经过多次跃点传输后,IP数据包最终到达目标主机。
在接收方,IP层从网络中接收IP数据包,并解析报文段。
然后,它将这些报文段传递给TCP层。
TCP层根据报文段的序号和确认机制,将它们按照正确的顺序组合成原始数据,然后将数据传递给接收方的应用程序。
通过TCP和IP协议的组合,TCP/IP实现了可靠的端到端通信。
TCP提供了数据的可靠传输,而IP负责将数据从源主机传输到目标主机。
TCP/IP的工作原理保证了数据的完整性和可靠性,使得通信系统非常可靠和稳定。
inet_atonl用法socket
inet_atonl用法socket一、概述在S oc ke t编程中,i n et_a to nl是一个用于将I Pv4地址转换为二进制形式的函数。
本文将介绍i ne t_at on l函数的用法,并提供一些示例代码来帮助读者更好地理解其功能。
二、i n e t_a t o n l函数的定义和用法i n et_a to nl函数属于网络编程中的套接字编程库,其功能是将形如"192.168.0.1"的IP v4地址转换为网络字节序的二进制形式。
其函数原型如下:i n_a dd r_ti ne t_ato n l(co ns tc ha r*cp);参数cp是指向存储I P v4地址字符串的指针,函数返回值为一个32位的无符号整数,表示转换后的I Pv4地址。
接下来,我们将通过一些示例代码来展示i ne t_at on l函数的用法。
三、示例代码1.转换I P v4地址为二进制形式#i nc lu de<s td io.h>#i nc lu de<s td li b.h>#i nc lu de<a rp a/ine t.h>i n tm ai n(){c o ns tc ha r*ip_a ddr e ss="192.168.0.1";i n_a dd r_tb in ar y_a d dr es s=in et_a ton l(i p_ad dr es s);p r in tf("Bi na ry add r es s:%u\n",bi nar y_a dd re ss);r e tu rn0;}上述示例代码演示了将I Pv4地址字符串"192.168.0.1"转换为二进制形式的过程。
输出结果将显示转换后的二进制地址。
2.错误处理#i nc lu de<s td io.h>#i nc lu de<s td li b.h>#i nc lu de<a rp a/ine t.h>i n tm ai n(){c o ns tc ha r*ip_a ddr e ss="192.168.0.256";i n_a dd r_tb in ar y_a d dr es s=in et_a ton l(i p_ad dr es s);i f(b in ar y_ad dr ess==-1){p r in tf("In va li dIP a dd re ss\n");r e tu rn-1;}p r in tf("Bi na ry add r es s:%u\n",bi nar y_a dd re ss);r e tu rn0;}上述示例代码演示了当提供的IP v4地址字符串无效时,如何进行错误处理。
网络字节序转换函数(64位)
网络字节序转换函数(64位)在网络编程里,网络字节序是big-endian的,而大部分的PC的系统都是X86处理器系列,X86采用的是little-endian,所以需要将网络数据流转换成本地数据流的话,需要进行字节序的转换。
标准库里提供了hlton()和nthl()两个函数来支持转换。
hston(unsigned short), hlton(unsigned long) 将本地字节序转换为网络字节序ntohl(unsigned long), ntohs(unsigned short) 将网络字节序转换为本地字节序但是对于64位的整数进行转换,标准库并没有提供相应的转换函数,本文将给出个人原创的64位字节序转换函数。
#ifndef ULONG64#define unsigned long long ULONG64#endif// host long 64 to networkULONG64 hl64ton(ULONG64 host){ULONG64 ret = 0;ULONG high,low;low = host & 0xFFFFFFFF;high = (host >> 32) & 0xFFFFFFFF;low = htonl(low);high = htonl(high);ret = low;ret <<= 32;ret |= high;return ret;}//network to host long 64ULONG64 ntohl64(ULONG64 host) {ULONG64 ret = 0;ULONG high,low;low = host & 0xFFFFFFFF;high = (host >> 32) & 0xFFFFFFFF; low = ntohl(low);high = ntohl(high);ret = low;ret <<= 32;ret |= high;return ret;}关于little endian和big endian的详细信息,网上的资料太多了,本文就不详述了。
大端和小端(BigendianandLittleendian)
⼤端和⼩端(BigendianandLittleendian)⼀、⼤端和⼩端的问题对于整型、长整型等数据类型,Big endian 认为第⼀个字节是最⾼位字节(按照从低地址到⾼地址的顺序存放数据的⾼位字节到低位字节);⽽ Little endian 则相反,它认为第⼀个字节是最低位字节(按照从低地址到⾼地址的顺序存放据的低位字节到⾼位字节)。
例如,假设从内存地址 0x0000 开始有以下数据:0x0000 0x0001 0x0002 0x00030x12 0x34 0xab 0xcd如果我们去读取⼀个地址为 0x0000 的四个字节变量,若字节序为big-endian,则读出结果为0x1234abcd;若字节序为little-endian,则读出结果为0xcdab3412。
如果我们将0x1234abcd 写⼊到以 0x0000 开始的内存中,则Little endian 和 Big endian 模式的存放结果如下:地址 0x0000 0x0001 0x0002 0x0003big-endian 0x12 0x34 0xab 0xcdlittle-endian 0xcd 0xab 0x34 0x12⼀般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,⽹络字节顺序也是 big-endian还有的CPU 能通过跳线来设置 CPU ⼯作于 Little endian 还是 Big endian 模式。
对于0x12345678的存储:⼩端模式:(从低字节到⾼字节)地位地址 0x78 0x56 0x34 0x12 ⾼位地址⼤端模式:(从⾼字节到低字节)地位地址 0x12 0x34 0x56 0x78 ⾼位地址⼆、⼤端⼩端转换⽅法htonl() htons() 从主机字节顺序转换成⽹络字节顺序ntohl() ntohs() 从⽹络字节顺序转换为主机字节顺序Big-Endian转换成Little-Endian#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | (((uint32)(A) & 0x00ff0000) >> 8) | \(((uint32)(A) & 0x0000ff00) << 8) | (((uint32)(A) & 0x000000ff) << 24))三、⼤端⼩端检测⽅法如何检查处理器是big-endian还是little-endian?C程序:int i = 1;char *p = (char *)&i;if(*p == 1)printf("Little Endian");elseprintf("Big Endian");⼤⼩端存储问题,如果⼩端⽅式中(i占⾄少两个字节的长度)则i所分配的内存最⼩地址那个字节中就存着1,其他字节是0.⼤端的话则1在i的最⾼地址字节处存放,char是⼀个字节,所以强制将char型量p指向i则p指向的⼀定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是⼩端。
inet_ntop函数
inet_ntop函数inet_ntop函数是一个C语言函数,用于将网络字节序的IPv4或IPv6地址转换成文本表示形式(即点分十进制表示法)。
它是inet_ntoa函数的升级版本,它支持IPv4和IPv6地址,而inet_ntoa 只支持IPv4地址。
inet_ntop函数的原型如下:const char * inet_ntop(int af, const void * src, char * dst, socklen_t size);它有四个参数:1. af:地址族,可以是AF_INET(IPv4)或AF_INET6(IPv6)2. src:指向指定地址族的IP地址的指针3. dst:指向存储文本表示形式的IP地址的缓冲区的指针4. size:缓冲区大小如果函数调用成功,它将返回指向缓冲区的指针,该缓冲区将包含文本表示形式的IP地址;如果函数调用失败,将返回NULL。
为了使用inet_ntop函数,必须先将IP地址从文本表示形式转换为网络字节序,可以使用inet_pton函数完成此操作。
#include <stdio.h>#include <arpa/inet.h>int main(int argc, char* argv[]) {char ipaddr[20];struct in_addr ip;inet_pton(AF_INET, "192.168.2.1", &ip);inet_ntop(AF_INET, &ip, ipaddr, sizeof(ipaddr));printf("%s\n", ipaddr);return 0;在上面的示例程序中,我们将IPv4地址从文本表示形式转换为网络字节序,然后使用inet_ntop函数将其转换回文本表示形式,最终得到的结果是:192.168.2.1。
总之,inet_ntop函数是一个用于将网络字节序的IPv4或IPv6地址转换成文本表示形式(即点分十进制表示法)的函数,它可以让我们更容易地查看和使用IP地址,因此在网络编程中非常有用。
高低字节序转换(htonl、ntohl、htons、ntohs函数)
高低字节序转换(htonl、ntohl、htons、ntohs函数)Part 1: htons函数具体解释在Linux和Windows网络编程时需要用到htons和htonl函数,用来将主机字节顺序转换为网络字节顺序。
在Intel机器下,执行以下程序int main()...{printf("%d /n",htons(16));return 0;}得到的结果是4096,初一看感觉很怪。
解释如下,数字16的16进制表示为0x0010,数字4096的16进制表示为0x1000。
由于Intel机器是小尾端,存储数字16时实际顺序为1000,存储4096时实际顺序为0010。
因此在发送网络包时为了报文中数据为0010,需要经过htons进行字节转换。
如果用IBM 等大尾端机器,则没有这种字节顺序转换,但为了程序的可移植性,也最好用这个函数。
另外用注意,数字所占位数小于或等于一个字节(8 bits)时,不要用htons转换。
这是因为对于主机来说,大小尾端的最小单位为字节(byte)。
Part 2: 大小端模式不同的CPU有不同的字节序类型这些字节序是指整数在内存中保存的顺序这个叫做主机序最常见的有两种1. Little endian:将低序字节存储在起始地址2. Big endian:将高序字节存储在起始地址LE little-endian最符合人的思维的字节序地址低位存储值的低位地址高位存储值的高位怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位反之,高位值就应该放在内存地址大的地方,也即内存地址高位BE big-endian最直观的字节序地址低位存储值的高位地址高位存储值的低位为什么说直观,不要考虑对应关系只需要把内存地址从左到右按照由低到高的顺序写出把值按照通常的高位到低位的顺序写出两者对照,一个字节一个字节的填充进去例子:在内存中双字0x01020304(DWORD)的存储方式内存地址4000 4001 4002 4003LE 04 03 02 01BE 01 02 03 04例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为big-endian little-endian0x0000 0x12 0xcd0x0001 0x23 0xab0x0002 0xab 0x340x0003 0xcd 0x12x86系列CPU都是little-endian的字节序.网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。
网络字节序与主机字节序的转换
⽹络字节序与主机字节序的转换在对IP地址结构体SOCKADDR_IN赋值的时候,经常会⽤到下列的函数htonl,htons,inet_addr,与之相对应的函数是ntohl,ntohs,inet_ntoa。
查看这些函数的解析,会发现这些函数其实是与主机字节序和⽹络字节序之间转换有关。
就是什么⽹络字节序,什么是主机字节序呢?下⾯我写出他们之间的转换:⽤IP地址127.0.0.1为例:第⼀步 127 . 0 . 0 . 1 把IP地址每⼀部分转换为8位的⼆进制数。
第⼆步 01111111 00000000 00000000 00000001 = 2130706433 (主机字节序)然后把上⾯的四部分⼆进制数从右往左按部分重新排列,那就变为:第三步 00000001 00000000 00000000 01111111 = 16777343(⽹络字节序)然后解析上⾯提到的函数作⽤就简单多了,看以下代码:SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);先是定义了⼀个IP地址结构体addrSrv,然后初始化它的IP时addrSrv.sin_addr.S_un.S_addr必须是赋值IP地址的⽹络字节序,htonl函数的作⽤是把⼀个主机字节序转换为⽹络字节序,也就是上⾯转换过程中第⼆步转换为第三步的作⽤,127.0.0.1的主机字节序是2130706433,把主机字节序2130706433转换为⽹络字节序就是htonl(2130706433)=16777343,所以如果你知道⽹络字节序是16777343的话,addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);与addrSrv.sin_addr.S_un.S_addr=16777343;是完全⼀样的。
TCPIP基本原理
TCPIP基本原理TCP/IP是一种网络协议套件,以传输控制协议(TCP)和互联网协议(IP)为核心,构建起了现代互联网的基础。
它包含了一系列的网络协议,用于实现在互联网上的数据传输和通信。
TCP/IP协议可以分为四个层次:网络接口层、网络层、传输层和应用层。
在TCP/IP协议中,网络接口层负责将数据包从主机发送到网络,或者从网络发送到主机。
这一层为物理寻址、链路控制和错误校验等提供了基础。
常见的网络接口层协议有以太网、Wi-Fi和蓝牙等。
网络层是TCP/IP协议的核心部分,主要负责网络间的路径选择和数据包的路由。
其中IP协议是网络层的核心协议,它为每个连接到互联网上的设备分配唯一的IP地址,实现了设备的全球互联。
IP协议将数据包分割成小块,并选择最佳的路由路径将它们发送到目标设备。
传输层是在网络层和应用层之间建立端到端通信的层次。
它为应用程序提供了可靠的数据传输服务。
TCP协议是传输层的核心协议,它通过建立连接、数据分割、错误检测和重传等机制,确保数据的可靠传输。
UDP协议是另一种传输层协议,它提供了无连接的、不可靠的数据传输服务,适用于实时传输或者对数据丢失不敏感的应用。
应用层是用户与网络之间的接口,它定义了各种应用程序和网络之间的通信规则。
常见的应用层协议有HTTP、FTP、SMTP和DNS等。
这些协议定义了数据的格式和传输方式,使得不同的应用程序能够进行互操作。
TCP/IP协议套件具有以下几个基本特点:1.可扩展性:TCP/IP协议套件具有很高的可扩展性,可以根据不同网络需求进行调整和扩展。
2.松散耦合:TCP/IP协议套件中的各个协议是相对独立的,它们可以单独工作,也可以结合在一起使用。
3.开放标准:TCP/IP协议是一种开放标准,任何人都可以使用和扩展它,这也是互联网的一个重要特点。
4.网络层次结构:TCP/IP协议套件是按照层次结构组织的,每一层都有自己的功能和任务,可以有效地分离和管理不同的网络功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TCP/IP网络字节顺序转换函数htonl、ntohl、、htons、ntohs
2010年06月27日星期日 13:12
套接字两种地址表示结构第一种sockaddr,第二种sockaddr_in,这两种结构大小相同且对应,可以相互转换,通常sockaddr_in更为常用。
struct sockaddr {
unsigned short sa_family;
char sa_data[14];
};
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr {
union {
struct{
unsigned char s_b1,
s_b2,
s_b3,
s_b4;
} S_un_b;
struct {
unsigned short s_w1,
s_w2;
}S_un_w;
unsigned long S_addr;
} S_un;
};
由于不同cpu储存数据的形式(顺序)不同,比如存储0x1234,在Inter的cpu里储存方式是从低位开始存储:34 12,而IBM的cpu储存从高位开始存储:12 34,网络上传输的方式就是与从高位开始,为了与网络传输字节顺序兼容于是出现了几个转换函数,它们是:
u_long inet_addr (const char FAR * cp);//1、主机字符串地址转换成网络long形式
char FAR * inet_ntoa (struct in_addr in ); //2、网络long形式转换成主机字符串
u_long PASCAL htonl(u_long); //3、主机到网络long形转换
u_long PASCAL ntohl(u_long); //4、网络到主机long形转换
u_short PASCAL htons(u_short); //5、主机到网络short形转换
u_short PASCAL ntohs(u_short); //6、网络到主机short形转换
其中1和3,2和4作用相同,只是转换到主机的时候2用字符串显示,4用long形数据显示。
比如要把一个主机ip地址格式转换成网络地址格式,如127.1.2.17的端口1234,可以这么写:
#define s_addr S_un.S_addr//winsock2.h
sockaddr_in addr;
addr.sin_addr.S_addr = inet_addr("127.1.2.3");//方便我们填写地址
addr.sin_addr.S_addr = htonl(0x7F010211);//在主机里就是怎么表示ip地址的
addr.sin_port = htons(1234); //1234的16进制0x04D2
使用printf("addr:0x%x\nport:0x%x\n",addr.sin_addr.S_addr,addr.sin_port);输出你会发现输出:
addr:0x1102017F
port:0x2D40
需要输出正确主机表示的形式把改成:
printf("addr:0x%x\nport:0x%x\n",ntohl(addr.sin_addr.S_addr),
ntohs(addr.sin_port));即可。
如何记忆上面的6个函数呢,其中1、2上面已经说明,看传递的参数即可知晓。
你只需知道在网络上目前ip地址是用32位表示(long形),port用16位表示(short形),那么看到函数的结尾是l的就是转换ip地址,结尾是s的就是转换port。