主机字节序和网络字节序

来源:互联网 发布:深圳青年旅社知乎 编辑:程序博客网 时间:2024/05/22 15:10
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网络编程

0 0
原创粉丝点击