Linux网络基础


    一、字节序

    字节序就是多字节数据在计算机中存储或者网络传输过程中地址高低与字节高低顺序关系问题。

    大端(big-endian):高地址位存低字节

    小端(little-endian):低地址位存低字节

    比如:0x0102的存储:

                               

                  地址递增

            大端:        01                    02

            小端:        02                    01

    计算机有的是大端有的是小端,但是网络字节序都是大端,所以需要转换。

    Linux提供了四个转换函数:    

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong); /*32位主机数据转换为网络字节序的数据*/

uint16_t htons(uint16_t hostshort); /*16位的主机字节序转换为网络字节序*/

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort); /*逆函数*/

    测试网络字节序:

      

#include 
    
    
     
     
#include 
     
     
      
      

int main(int argc, char **argv)
{
    
        int  a = htons(0x0102);
        int* p = &a ;
        
        if(    *((char*)p)      ==      0x01        )
                printf("        big-endian    \n");
        if(     *((char*)p)     ==      0x02    )
                printf("        little -endian         \n");
                
	return 0;
}

     
     
    
    

    测试主机字节序:

#include 
   
   
    
    
#include 
    
    
     
     

int main(int argc, char **argv)
{
    
        int  a = 0x0102;
        int* p = &a ;
        if(    *((char*)p)      ==      0x01        )   
                printf("        big-endian    \n");
        else
                printf("        little -endian         \n");
                
	return 0;
}

    
    
   
   

二、地址结构
Linux中IP地址结构定义:
#include <netinet/in.h>

struct in_addr
{
      in_addr_t s_addr  ;  /*in_addr_t被定义为无符号整型*/
}

进程使用16位端口号唯一标识。

Linux 地址结构:

#include <netinet/in.h>

/**Linux中网络通信地址结构块/
struct socketaddr_in
{
	sa_family_t sin_family;  /*16位的地址族*/
	in_port_t sin_port;      /*16位端口号*/
	struct in_adddr sin_addr ;  /*32位IP地址*/
	unsigned char sin_zero[8];  /* 填充去区,8个字节填“0”*/
}


 地址族是根据套接字使用场合不同,会使用不同的地址族,网络通信,使用AF_NET
填充区是为了socketaddr_in和socketaddr结构随意转换
socketaddr结构如下:

#include <netinet/in.h>

struct socketaddr
{
     sa_family sa_family;/*16位地址族*/
     char sa_data[14];/*14字节填充区*/
}

这两个结构等长,方便强制类型转换


地址形式转换:

二进制转换十进制点分形式

十进制转换二进制

#include <netinet/in.h>


const char * inet_ntop(int domain , const void * restrict addr ,cahr * restrict str , socklen_t size) ;


int  inet_pton(int domain , const char * restrict str ,void * restrict addr) ;


domain参数可以是AF_INET或者AF_INET6,地址长度不同;addr表示二进制形式的IP地址;

参数str指向的区域存储IP地址的点分十进制形式的字符串,参数size表示的是该区域的大小,以防止因为地址格式不对导致的越界访问。

因为IP地址字符串形式缓冲区最大为(Iv6地址):3*4+3+1 = 16(字节)

inet_ntop是将二进制转换为十进制

成功返回字符串首地址,地址不对返回0,错误返回-1


 inet-pton是上述函数的逆函数

成功返回1



获取主机信息:
函数原型:
#include 
    
    
     
     

struct hostent * gethostent(void) ;
/*该函数从系统/etc/hosts文件中读取主机相关信息*/

#include 
     
     
      
      
struct hostent
{
    char *h_name ;/*正式主机名,只有一个*/
    char ** h_aliases;/*主机列表名*/
    int h_addrtype;/*IP地址类型可以是v4或者v6*/
    int h_length;/*IP地址长度,*/
    char ** h_addr_list;/*IP地址列表h_addr_list[0]为主机的IP地址*/
}
     
     
    
    

获取主机信息例子:
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#define NET_ADDR 16

int main(int argc, char **argv)
{
	struct hostent *host ;
        char addr_p[NET_ADDR];
        int i ;
        
        if((host = gethostent()) == NULL)
        {
            printf("error");
            exit(1);
        }
        
        printf("%s\n",host->h_name) ;
        
        for(i=0;   host->h_aliases[i]!=NULL;  i++)
        {
            printf("%s\n",host->h_aliases[i]);
        }
        if(host->h_addrtype == AF_INET)
            printf("AF_INET\n");
        else 
            printf("unix_inet\n");
        
        printf("%d\n", host->h_length) ;
        
        for(i = 0 ;host->h_addr_list[i]!=NULL;i++)
        {
            printf("%s\n",inet_ntop(host->h_addrtype,host->h_addr_list[i],addr_p,NET_ADDR));
        }
	return 0;
}
       
       
      
      
     
     
    
    







 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值