主机字节序和网络字节序
2014-09-06 20:41
169 查看
1.判断主机字节序
#include <iostream>
using namespace std;
union Test
{
int val;
char t[2];
};
int main()
{
union Test tt;
tt.val=0x1234;
if(tt.t[0]==0x34 && tt.t[1]==0x12)
cout<<"Small endian"<<endl;
else
cout<<"big endian"<<endl;
return 0;
}
2.socket API中我们使用过许多转换函数
例如inet_addr, htons, htonl, ntohl, ntohs等等(注意这几个是跨平台的)
htons,htonl 表示将主机字节次序转换为网络字节次序(s表示short, l表示long)
ntohs,ntohl 表示将网络字节次序转换为主机字节次序(s表示short, l表示long)
inet_addr (The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data in network byte order.) 将网络主机地址(ipv4)转换为网络表示的地址,但是这种方法有个缺陷(当地址为255.255.255.25时, 在linux下会有问题)
现在我们尝试以上函数的具体实现:
#include <iostream>
#include <ctype.h>
#include <arpa/inet.h> //struct addr structure
#include <stdio.h> //sprintf function useit
using namespace std;
unsigned short htons(unsigned short src)
{
//unsigned char* p = (unsigned char*)&src;
//return (unsigned short)(p[0]<<8 | p[1]);
return (src & 0xff00)>>8 | (src & 0x00ff)<<8;
}
unsigned short ntohs(unsigned short src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned short)(p[0]<<8 | p[1]);
}
unsigned long htonl(unsigned long src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned long)(p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]);
}
unsigned long ntohl(unsigned long src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned long)(p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]);
}
char* inet_ntoa(struct in_addr addr)
{
static char buf[16] = {'\0'};
unsigned char* p = (unsigned char*)&addr;
sprintf(buf,"%d.%d.%d.%d",p[0], p[1], p[2], p[3]);
return buf;
}
long net_addr(const char *str)
{
long a, b, c, d;
sscanf(str, "%ld.%ld.%ld.%ld", &a, &b, &c, &d);
long addr = 0;
addr |= d<<24; //d<<24之间千万不要有空格
addr |= c<<16;
addr |= b<<8;
addr |= a;
return addr;
}
int main()
{
unsigned short host_s = 0x1234,net_s;
unsigned long host_l =0x12345678,net_l;
char *addr_dec = "192.168.10.26",*p;
struct in_addr addr;
net_s = htons(host_s);
net_l = htonl(host_l);
cout<<host_s <<" "<<net_s<<endl;
cout<<host_l<<" "<<net_l<<endl;
addr.s_addr = net_addr(addr_dec);
p = inet_ntoa(addr);
cout<<addr.s_addr<<" "<<p<<endl;
return 0;
}
在系统函数下的测试:
#include <iostream>
//#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
unsigned short host_s = 0x1234,net_s;
unsigned long host_l =0x12345678,net_l;
char *addr_dec = "192.168.10.26",*p;
struct in_addr addr;
net_s = htons(host_s);
net_l = htonl(host_l);
cout<<host_s <<" "<<net_s<<endl;
cout<<host_l<<" "<<net_l<<endl;
addr.s_addr = inet_addr(addr_dec);
p = inet_ntoa(addr);
cout<<addr.s_addr<<" "<<p<<endl;
return 0;
}
get the same result:
4660 13330
305419896 2018915346
436906176 192.168.10.26
参考书籍: WInSock网络编程
#include <iostream>
using namespace std;
union Test
{
int val;
char t[2];
};
int main()
{
union Test tt;
tt.val=0x1234;
if(tt.t[0]==0x34 && tt.t[1]==0x12)
cout<<"Small endian"<<endl;
else
cout<<"big endian"<<endl;
return 0;
}
2.socket API中我们使用过许多转换函数
例如inet_addr, htons, htonl, ntohl, ntohs等等(注意这几个是跨平台的)
htons,htonl 表示将主机字节次序转换为网络字节次序(s表示short, l表示long)
ntohs,ntohl 表示将网络字节次序转换为主机字节次序(s表示short, l表示long)
inet_addr (The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data in network byte order.) 将网络主机地址(ipv4)转换为网络表示的地址,但是这种方法有个缺陷(当地址为255.255.255.25时, 在linux下会有问题)
现在我们尝试以上函数的具体实现:
#include <iostream>
#include <ctype.h>
#include <arpa/inet.h> //struct addr structure
#include <stdio.h> //sprintf function useit
using namespace std;
unsigned short htons(unsigned short src)
{
//unsigned char* p = (unsigned char*)&src;
//return (unsigned short)(p[0]<<8 | p[1]);
return (src & 0xff00)>>8 | (src & 0x00ff)<<8;
}
unsigned short ntohs(unsigned short src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned short)(p[0]<<8 | p[1]);
}
unsigned long htonl(unsigned long src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned long)(p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]);
}
unsigned long ntohl(unsigned long src)
{
unsigned char* p = (unsigned char*)&src;
return (unsigned long)(p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]);
}
char* inet_ntoa(struct in_addr addr)
{
static char buf[16] = {'\0'};
unsigned char* p = (unsigned char*)&addr;
sprintf(buf,"%d.%d.%d.%d",p[0], p[1], p[2], p[3]);
return buf;
}
long net_addr(const char *str)
{
long a, b, c, d;
sscanf(str, "%ld.%ld.%ld.%ld", &a, &b, &c, &d);
long addr = 0;
addr |= d<<24; //d<<24之间千万不要有空格
addr |= c<<16;
addr |= b<<8;
addr |= a;
return addr;
}
int main()
{
unsigned short host_s = 0x1234,net_s;
unsigned long host_l =0x12345678,net_l;
char *addr_dec = "192.168.10.26",*p;
struct in_addr addr;
net_s = htons(host_s);
net_l = htonl(host_l);
cout<<host_s <<" "<<net_s<<endl;
cout<<host_l<<" "<<net_l<<endl;
addr.s_addr = net_addr(addr_dec);
p = inet_ntoa(addr);
cout<<addr.s_addr<<" "<<p<<endl;
return 0;
}
在系统函数下的测试:
#include <iostream>
//#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
unsigned short host_s = 0x1234,net_s;
unsigned long host_l =0x12345678,net_l;
char *addr_dec = "192.168.10.26",*p;
struct in_addr addr;
net_s = htons(host_s);
net_l = htonl(host_l);
cout<<host_s <<" "<<net_s<<endl;
cout<<host_l<<" "<<net_l<<endl;
addr.s_addr = inet_addr(addr_dec);
p = inet_ntoa(addr);
cout<<addr.s_addr<<" "<<p<<endl;
return 0;
}
get the same result:
4660 13330
305419896 2018915346
436906176 192.168.10.26
参考书籍: WInSock网络编程
相关文章推荐
- 网络字节序与主机字节序
- 网络字节序和主机字节序
- 关于网络字节序(network byte order)和主机字节序(host byte order)
- 网络字节序与主机字节序
- 网络字节序与主机字节序的转换
- 网络字节序与主机字节序
- 网络字节序与主机字节序
- 网络字节序和主机字节序笔记
- 网络字节序和主机字节序
- 网络编程中的网络字节序与主机字节序
- 【转】网络字节序与主机字节序
- 网络字节序与主机字节序
- 关于网络字节序和主机字节序
- 大端字节序、小端字节序、主机字节序、网络字节序
- 网络字节序与主机字节序
- 网络字节序和主机字节序
- 网络字节序与主机字节序
- 网络字节序与主机字节序
- 网络字节序与主机字节序
- 主机字节序与网络字节序