网络编程 day01 (linux ) 网络字节序 与 主机字节序的转化函数 ,与相关的知识 。

1.网络编程的知识:


2.


 3.


4.


5.TCP/IP协议

下面我们来简要了解TCP/IP的四层模型:

网络接口层:负责将二进制流转换为数据帧,并进行数据帧的发送和接收。数据帧是网络信息传输的基本单元,ARP和RARP协议。

网络层:负责将数据帧封装成IP数据报,同时负责选择数据报的路径,即路由,IP和ICMP协议。

传输层:负责端到端之间的通信会话连接与建立,传输协议的选择根据数据传输方式而定,UDP和TCP协议。

应用层:负责应用程序的网络访问,这里通过端口号来识别各个不同的进程,FTP、TELNET、DNS、SMTP、POP3 协议。


6.


7.


8.


9.TCP协议特点

1.TCP(即传输控制协议):是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)

2.适用情况: 适合于对传输质量要求较高,以及传输大量数据的通信。

在需要可靠数据传输的场合,通常使用TCP协议

MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议


10.TCP/IP网络编程预备知识

Socket:一种不同主机间通信的文件

IP地址:标记不同主机

端口号:标记不同应用程序

字节序:传输规则


11.Socket 简介

Socket 是一个编程接口

是一种特殊的文件描述符 (everything in Unix is a file)

并不仅限于TCP/IP协议

面向连接 (Transmission Control Protocol - TCP/IP)

无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX)


12.Socket类型

流式套接字(SOCK_STREAM)       

提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。

数据报套接字(SOCK_DGRAM)         

提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。

原始套接字(SOCK_RAW)                     

 可以对较低层次协议如IP、ICMP直接访问。


13.IP地址

IP地址是Internet中主机的标识 Internet中的主机要与别的机器通信必须具有一个IP地址

IP地址为32位(IPv4)或者128位(IPv6) 每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由。

表示形式:常用十进制点分形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。


14.IP地址的转换(函数)

 htonl( );主机字节序数值 转换为 网络字节序数值

ntohl();网络字节序数字 转化为 主机字节序数字

inet_aton() 将strptr所指的字符串转换成32位的网络字节序二进制值的数字

inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值

inet_ntoa  将32位网络字节序二进制地址  转换成点分十进制的字符串。

inet_pton()   函数 主机字节序的字符串 转换为 网络字节序的数值

inet_ntop()  函数 网络字节序的数值 转换为 主机字节序的字符串


15.代码:

 htonl( );主机字节序数值 转换为 网络字节序数值

ntohl();网络字节序数字 转化为 主机字节序数字

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:主机字节序 转 网络字节序  
 		网路字节序 转 主机字节序
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
// host  -- to  -- network  -- l : int  s: short
// htonl   

int main(int argc,char *argv[])
{

	//主机字节序 转换为 网络字节序 
	int num =0x01020304;
	int net_order = htonl(num);
	printf("net_order = %#x\n",net_order);
	

	//网络字节序 转化为 主机字节序
	// network --  to --  host    l :int 
	int host_order=ntohl(net_order);
	printf("host_order=%#x\n",host_order);

       return 0;

}

16.代码:

inet_aton() 将strptr所指的字符串转换成32位的网络字节序二进制值的数字

inet_ntoa  将32位网络字节序二进制地址  转换成点分十进制的字符串。

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>

//主机字节序 : 1. 整数/数值  2.字符串   
//网络字节序 : 数值
//主机 ip 地址 (十进制点分形式 字符串)
//主机字符串 转换为 网络字节序数值函数    inet_aton() 
//反过来  inet_ntoa() 数字转换为字符串



int main(int argc,char *argv[])
{

	//主机字节序 的字符串转换为 网络字节序的数字
	char *ip="192.168.1.101";
	struct in_addr res ={0};
	int flg =inet_aton(ip,&res);//转换成功返回1
	printf("flg =%d   res =  %#x\n",flg,res.s_addr);

	
	// 网络字节序数字 转化为  主机字符串
	printf("host is %s\n",inet_ntoa(res));
       return 0;

}

17.代码:

inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值

inet_pton()   函数 主机字节序的字符串 转换为 网络字节序的数值

inet_ntop()  函数 网络字节序的数值 转换为 主机字节序的字符串

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:函数 inet_pton 函数
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
//
//1.inet_pton() 函数 主机字节序的字符串 转换为 网络字节序的数值
//2.inet_ntop() 函数 网络字节序的数值 转换为 主机字节序的字符串
//3.inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值
// 
//第一个的
//原型: int inet_pton(int af,const char*stc,void *det);
//参数: af: AF_   INET IPV4
//		 stc 要转化的字符串 
//		 det 转换的结果,整形变量的地址
//返回值 : 成功 1 不成功: -1   没有转换的数据 0 
//
//第三个   
//原型: in_addr_t inet_addr(const char *cp);
//参数 ;cp :十进制点分形式的ip字符串
//返回值:网络字节序
//
//
//第二个 
//原型: const char *inet_ntop(int af ,const void src,char *dsr socklen_t size)
//参数: af AF_IENT
//        src 要转化的网络字符串
//        dsr : 转化完的字符串
//        size dsr的空间大小
//返回值:转换完的字符串
//

int main(int argc,char *argv[])
{
	char *str="192.168.1.101";
	unsigned int net_order=0;
//1.inet_pton() 函数 主机字节序的字符串 转换为 网络字节序的数值
	int res =inet_pton(AF_INET,str,&net_order);
	if(res <0)
	{
		perror("inet_pton  error\n");
		return -1;
	}
	printf("res =%d   inet_pton= %u\n",res,net_order);
	

//3.inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值
	in_addr_t netorder1 = inet_addr(str);
	printf("netorder  = %u\n",netorder1);


//2.inet_ntop() 函数 网络字节序的数值 转换为 主机字节序的字符串
	char ip[20]="";

	const char* ipstr = inet_ntop(AF_INET,&net_order,ip,sizeof(ip));
	printf("host ip = %s\n",ip);
	printf("ipstr =%s \n",ipstr);

       return 0;

}

18.测试代码 :测试大端(网络字节序)  小端 (主机字节序)的存储方式的不同

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:网络编程
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
//查看数据在内存中的存储
//网络字节序 是大端存储的字节序, 是在两个电脑传输的时候用的东西
//主机字节序 是小端存储的字节序  是在自己的一个电脑上传输数据的东西
int main(int argc,char *argv[])
{
	int num =0x01020304;   //主机字节序  数据的存储  也叫小端存储
	char *p=(char *)&num;  //p 指向低地址
	int i;
	//真理 验证
	for(i=0;i<4;i++)
	{
		printf("%p  %#x\n",p,*p);  //%#x  十六进制的输出 
		p++;
	}





       return 0;

}

19.端口号

为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别

TCP端口号与UDP端口号独立

端口号一般由IANA (Internet Assigned Numbers Authority) 管理 众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)

已登记端口:1024~49151

动态或私有端口:49152~65535


20.


21.字节序

不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO): 小端序(little-endian) - 低序字节存储在低地址 将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式; 大端序(big-endian)- 高序字节存储在低地址 将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用

网络中传输的数据必须按网络字节序,即大端字节序

在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成小端字节序)

网络字节序(NBO - Network Byte Order) 使用统一的字节顺序,避免兼容性问题

主机字节序(HBO - Host Byte Order) 不同的机器HBO是不一样的,这与CPU的设计有关 Motorola 68K系列、ARM系列,HBO与NBO是一致的 Intel X86系列,HBO与NBO不一致


22.TCP/IP协议建立TCP连接的过程(三次握手)

A→B:主机A向主机B发送连接请求,报文中包括SYN控制标志,但没有数据。主机B收到SYN后,将其状态转化成SYN-RECEIVED

A←B:主机B向主机A发送建立连接请求,并会带队主机A的SYN确认。主机A收到消息后,将其状态变成ESTABLISHED

A→B:主机B收到主机A发来确认信息后,也将自身状态转化为ESTABLISHED,至此,一条TCP连接建立完毕。接下来就可以再两台主机间传输数据了

//建立连接-传输数据。


23.TCP/IP协议建立TCP关闭的过程 (四次挥手)

关闭TCP连接 发起连接的一方(主机A)

请求关闭TCP连接 主机B主动请求关闭TCP连接

主机A和主机B同时发起断开连接的请求。


24.打包 与 解包 的过程

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:socket 编程接口  是一种特殊的文件描述符号,并不限于TCP/IP 协议
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>

//struct sockaddr_in
//1.


//通用的网络编程接口: socket  位于会话层 和传输层 之间
//三种套接字 的类型
//SOCK_STREAM  流式套接字  TCP
//            数据报的套接字 UTP
// _sockaddr_in
int main(int argc,char *argv[])
{
	if(argc <3)//参数判断
	{
		perror("argc error\n");
		return -1;
	}

	//打包
	//----------------------------
	struct sockaddr_in saddr ={0};
	saddr.sin_family=AF_INET; //IPV4 协议族
	saddr.sin_addr.s_addr = inet_addr(argv[1]);//主机字节序 转换 网络字节序
	saddr.sin_port = htons(atoi(argv[2]));  //  端口号 字符串转换为主机字节序的整形 再次转化为 网络字节序的数字
	

	//解包
	//-------------------------------
	printf("sever port = %d\n",ntohs(saddr.sin_port));
	char ip[20]="";
	printf("server ip =%s \n",inet_ntop(AF_INET,&saddr.sin_addr.s_addr ,ip,sizeof(ip)));



       return 0;

}

25.函数;

//1.gethostname: 获取本主机的名称
//2.gethostbyname: 通过域名www.baidu.com  获得主机名
//3.sethostname  设置主机名 

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>

//1.gethostname: 获取本主机的名称
//2.gethostbyname: 通过域名www.baidu.com  获得主机名
//3.sethostname  设置主机名 
int main()
{
	/*
	char hostname1[100]="student-machine";
	if(!sethostname(hostname1,strlen(hostname1))) //设置主机名字
	{
		printf("set  host  = %s \n ",hostname1);
	}
	else
	{
		perror("set host error\n");
		return -2;
	}
	*/

	char hostname[200]="";
	if(!gethostname(hostname,sizeof(hostname))) //获取主机名字
	{
		printf("hostname =  %s \n",hostname);
	}
	else
	{
		printf("gethostname error\n");
		return -1;
	}

	//通过域名获取主机名字  
	char *str="www.baidu.com";
	struct hostent *host = gethostbyname(str);
	if(host ==NULL)
	{
		perror("gethostbyname error\n");
	}
	else
	printf("host name is %s\n",host->h_name);



	//输出别名
	while(*host->h_aliases !=NULL)  //->  .  []  成员运算符  优先级很强
	{
		printf("aliases  =%s  \n",*host->h_aliases);
		host->h_aliases++; //二级指针可以移位置 
	}
	

	//获取地址列表 
	char ip[100]="";
	while(*host->h_addr_list!=NULL)
	{
		printf("list : %s \n",inet_ntop(AF_INET,*host->h_addr_list,ip,sizeof(ip)));
		host->h_addr_list++;//二级指针可以移位置
	}



	
	



	return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值