Linux网络编程基础1:大小端 && 存储socket 地址

img

1.主机字节序和网络字节序

现在CPU的累加器一次能装载至少四字节,这四字节在内存中的排列顺序讲影响它被累加器装成的整数的值。现代PC大多采用小端字节序,所以被称为主机字节序。当不同字节序的主机传输问题时,会存在传输信息错误解释的结果。解决这个问题的方式就是:发送端要把发送的数据转化成大端字节序在网上传输,接收端知道网络传输都是大端所以要根据自身情况进行转化。大端叫网络字节序,小端叫主机字节序。

注意:即便同一台机器的两个进程通信,也要考虑大小端的问题,JAVA虚拟机采用的事大端字节序。通过测试,我的windows笔记本为小端。

#include<netinet/in.h>**unsigned long int htol (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);

任何格式化数据通过网络传输时,都应该用这些函数转字节序!

判断大端小端的函数~~

#include <stdio.h>
void byteorder()
{
	union
	{
		short value;
		char union_bytes[ sizeof( short ) ];
	} test;
	test.value = 0x0102;
	if (  ( test.union_bytes[ 0 ] == 1 ) && ( test.union_bytes[ 1 ] == 2 ) )
	{
		printf( "big endian\n" );
	}
	else if ( ( test.union_bytes[ 0 ] == 2 ) && ( test.union_bytes[ 1 ] == 1 ) )
	{
		printf( "little endian\n" );
	}
	else
	{
		printf( "unknown...\n" );
	}
}

2.通用socket地址

#include<bits/socket.h>
/* Structure describing a generic socket address.  */
struct sockaddr
  {
 	sa_family_t sa_family;	/* Common data: address family and length.  协议族 or 地址族*/
    char sa_data[14];		/* Address data.  不同地址族有不同的长度和含义*/
  };
  
/* Structure large enough to hold any socket address (with the historical
   exception of AF_UNIX).  */
struct sockaddr_storage
  {
   sa_family_t sa_family;	/* Address family, etc.  */
    unsigned long int __ss_align;	/* Force desired alignment.  */
    char __ss_padding[128-sizeof(__ss_align)];
  };

sockaddr_storage结构体提供了足够大的空间用于存放地址族,而且内存是对齐的。

3.专用socket地址

Linux各协议族提供了专门的socket地址结构体。
unix本地域使用专门socket地址结构体:

#include<sys/un.h>
/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
struct sockaddr_un
  {
   // __SOCKADDR_COMMON (sun_);
    sa_family_t sa_family;		/* AF_UNIX.  */
    char sun_path[108];		/* Path name.  */
  };

在这里插入图片描述

TCP/IP协议族有专用的socketaddr_in和sockaddr_in6,分别用于ipv4和ipv6

#include <netinet/in.h>
/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    sa_family_t  sin_family; /*地址族:AF_INET*/
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */
  };
  

在这里插入图片描述

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr; //ipv4地址,要用网络字节序表示
  };
  
/* Ditto, for IPv6.  */
struct sockaddr_in6
  {
    sa_family_t  sin6_family;
    in_port_t sin6_port;	/* Transport layer port # */
    uint32_t sin6_flowinfo;	/* IPv6 flow information */
    struct in6_addr sin6_addr;	/* IPv6 address */
    uint32_t sin6_scope_id;	/* IPv6 scope-id */
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

所有专用的socket地址类型(sockaddr_storage)都需要强制转化为地址类型sockaddr,所有的socket编程接口使用的参数都是sockaddr。

4.IP地址转化函数

#include<arpa/inet.h>
①in_addr_t inet_addr(const char * strptr);int inet_aton(const char *cp,struct in_addr* inp);char* inet_ntoa(struct in_addr in);

inet_addr函数用 点分十进制字符串 表示的IPv4地址转化为用网络字节序整数表示的IPv4地址。它失败时返回INADDR_NONE。
inet_aton函数完成和inet_addr同样的功能,但将结果存储于参数inp指向的地址结构体中。成功返回1,失败返回0.
inet_ntoa函数讲用网络字节序整数表示的IP地址转化为用 点分十进制字符串表示的IPv4地址。需要注意的是:该函数内部用一个静态变量存储转化结果,函数返回值指向该静态内存,所以是不可重入的。

#include<arpa/inet.h>int inet_pton(int af,const char * src,void *dst);const char* inet_ntop(int af,const void* src,char * dst,socklen_t cnt);

inet_pton函数将用字符串表示的IP地址src(用点分十进制字符串表示的IPv4地址或用十六进制字符串表示的IPv6地址)转化成用网络字节序证书表示的IP地址,并把转换结果存储于dst指向的内存中。其中,af参数指定地址族,可以是AF_INET或者AF_INET6。成功返回1,失败返回0并设置errno。

inet_ntop函数进行相反的转换,前三个参数的含义与inet_pton的参数相同,最后一个参数cnt指定目标存储单元的大小。成功时返回目标存储单元的地址,失败返回NULL并设置errno。指定大小的两个宏。

#include<netinet/in.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屯门山鸡叫我小鸡

加油

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值