千锋教育+计算机四级网络-计算机网络学习-03

目录

UDP编程准备

字节序概述

 如何判断自己主机上的大小端方式

大小端重点 

 大小端所需函数

htonl函数

ntohl函数

htons函数

ntohs函数

 地址转换函数

inet_pton函数

inet_ntop函数


 

UDP编程准备

字节序概述

字节序概念

是指多字节数据的存储顺序,一个字节是不存在存储顺序,并且多字节是一个整体,比如int类型的数据

分类

小端格式:将低位字节数据存储在低地址

大端格式:将高位字节数据存储在低地址

单片机中也存在这种分类,keil调试的时候也会出现这种情况,一般常见的都是小端的模式

注意

LSB:低地址

MSB:高地址

 因此小端格式和大端格式取数据的方式不一样,因此不必要担心数据会弄错,在同一台主机中,但是在不同主机就不一定了,因为有些计算机是大端模式,而有些是小端模式,那么就会出现问题了

大-高数低址  小-低数低址

 如何判断自己主机上的大小端方式

由于大小端的方式是系统确定好的,人为无法直接改变的

强制类型转换、联合体两种方式判断主机大小端(其实后面还有一种,借助字节序转换函数判断)

 

大小端重点 

1、网络协议指定了通讯字节序—大端

2、只有在多字节数据处理时才需要考虑字节序

3、运行在同一台计算机上的进程相互通信时,一般不用考虑字节序

4、异构计算机之间通讯,需要转换自己的字节序为网络字节序(大端)。在需要字节序转换的时候一般调用特定字节序转换函数

如果忽略了大小端会发生什么?--- 接收的数据会错误 

 因此为了更好的配合,就规定网络数据传输一定是大端数据

分析好上下三个图就成功了,不管你主机是大端还是小端,只要你使用了相应的函数(这个函数会自动检测主机的大小端模式),(如果发送端主机是小端)那么就会把数据自动转换为大端数据才发送到网络中去,(如果接收端主机是小段)那么网络的大端数据就会被先转换为小端数据再发送给接收端主机

 

 

 答案为a,画一个内存的图就出来了

 

 大小端所需函数

这四个函数,其中两个函数常用于IP地址传输,另外一个函数常用于端口传输。当然数据的转换也是使用这些函数的

htonl函数

uint32_t htonl(uint32_t hostint32);

功能:

将32位主机字节序数据转换成网络字节序数据--因此使用在发送端主机

一般由于转换IP地址的,把IP地址(32位)发送给接收端主机

参数:

hostint32:待转换的32位主机字节序数据

返回值:

成功:返回网络字节序的值

头文件:

#include <arpa/inet.h>

ntohl函数

uint32_t ntohl(uint32_t netint32);

功能:

将32位网络字节序数据转换成主机字节序数据--因此使用在接收端主机

一般将网络字节序的IP地址转换为主机的IP地址

参数:

uint32_t: unsigned int

netint32:待转换的32位网络字节序数据

返回值:

成功:返回主机字节序的值

头文件:

#include <arpa/inet.h>

 

记忆方式:host--主机  net--网络  host to net表示主机-网络转换

htons函数

uint16_t htons(uint16_t hostint16);

功能:

将16位主机字节序数据转换成网络字节序数据--因此使用在发送端主机

一般由于将发送端主机端口转换为网络字节序的端口

参数:

uint16_t:unsigned short int

hostint16:待转换的16位主机字节序数据

返回值:

成功:返回网络字节序的值

头文件:

#include <arpa/inet.h>

ntohs函数

uint16_t ntohs(uint16_t netint16);

功能:

将16位网络字节序数据转换成主机字节序数据

一般由于将网络字节序的端口转换为接收端主机的端口

参数:

uint16_t: unsigned short int

netint16:待转换的16位网络字节序数据

返回值:

成功:返回主机字节序的值

头文件:

#include <arpa/inet.h>

因此可以使用字节序函数进行判断你主机是大小端格式

把主机数据转换为网络数据,如果数据不变,说明主机是大端,如果数据变了,那么就是小端存储了

 

 

 地址转换函数

一般指的就是IP地址

inet_pton函数

int inet_pton(int family,const char *strptr, void *addrptr);

功能:

将点分十进制数串(字符串)转换成32位无符号整数,字符串IP地址转整型数据

使用于发数据

参数:

family       协议族 ---  IPV4转换为AF_INET  IPV6转换为AF_INET6

strptr       点分十进制数串

addrptr  32位(4字节)无符号整数的地址-因此类型可以为int

返回值:

成功返回1 、 失败返回其它

头文件:

#include <arpa/inet.h>

理解addrptr的意思:四个字节,保存着字符串的数字形式

#include <stdio.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])
{
	char *ip_str = "192.168.13.100";
	unsigned int ip_uint = 0;
	unsigned char * ip_p =NULL;//可以用char吗?
	
	inet_pton(AF_INET,ip_str,&ip_uint);
	printf("ip_uint = %d\n",ip_uint);
	
	ip_p = (unsigned char *) &ip_uint;
	printf("ip_uint = %d.%d.%d.%d\n",*ip_p,*(ip_p+1),*(ip_p+2),*(ip_p+3));

 

 

记忆方式:p是point点的意思,to,net

inet_ntop函数

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

功能:

将32位无符号整数转换成点分十进制数串,整型数据转字符串格式ip地址

使用于收数据

参数:

family          协议族

addrptr       32位无符号整数

strptr           点分十进制数串

len           strptr缓存区长度

len的宏定义

#define INET_ADDRSTRLEN   16  //for ipv4

#define INET6_ADDRSTRLEN  46  //for ipv6

返回值:

成功:则返回字符串的首地址

失败:返回NULL

头文件:

#include <arpa/inet.h>

对于IPV4是十六字节,对于字符串"198.162.100.100",就是16个字节

#include<stdio.h>
#include<arpa/inet.h>
int main()
{
	unsigned char ip[]={192,168,13,252};
	char ip_str[16];
	inet_ntop(AF_INET,(unsigned int *)ip,ip_str,16);
	printf("ip_str = %s\n",ip_str);
	return 0;

 因此对于一个IP地址的转换,你就涉及到了把字符串IP地址转换为32为数字,然后再使用字节序函数转换为大端数据才能传输

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值