• 网络编程 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();网络字节序数字 转化为 主机字节序数字

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:主机字节序 转 网络字节序  
    7. 网路字节序 转 主机字节序
    8. ****************************************************************************************************************************************************************************************************************************/
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. // host -- to -- network -- l : int s: short
    42. // htonl
    43. int main(int argc,char *argv[])
    44. {
    45. //主机字节序 转换为 网络字节序 
    46. int num =0x01020304;
    47. int net_order = htonl(num);
    48. printf("net_order = %#x\n",net_order);
    49. //网络字节序 转化为 主机字节序
    50. // network -- to -- host l :int
    51. int host_order=ntohl(net_order);
    52. printf("host_order=%#x\n",host_order);
    53. return 0;
    54. }

    16.代码:

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

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

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. #include
    42. //主机字节序 : 1. 整数/数值  2.字符串   
    43. //网络字节序 : 数值
    44. //主机 ip 地址 (十进制点分形式 字符串)
    45. //主机字符串 转换为 网络字节序数值函数    inet_aton()
    46. //反过来 inet_ntoa() 数字转换为字符串
    47. int main(int argc,char *argv[])
    48. {
    49. //主机字节序 的字符串转换为 网络字节序的数字
    50. char *ip="192.168.1.101";
    51. struct in_addr res ={0};
    52. int flg =inet_aton(ip,&res);//转换成功返回1
    53. printf("flg =%d res = %#x\n",flg,res.s_addr);
    54. // 网络字节序数字 转化为  主机字符串
    55. printf("host is %s\n",inet_ntoa(res));
    56. return 0;
    57. }

    17.代码:

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

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

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

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:函数 inet_pton 函数
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. #include
    42. //
    43. //1.inet_pton() 函数 主机字节序的字符串 转换为 网络字节序的数值
    44. //2.inet_ntop() 函数 网络字节序的数值 转换为 主机字节序的字符串
    45. //3.inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值
    46. // 
    47. //第一个的
    48. //原型: int inet_pton(int af,const char*stc,void *det);
    49. //参数: af: AF_ INET IPV4
    50. // stc 要转化的字符串 
    51. // det 转换的结果,整形变量的地址
    52. //返回值 : 成功 1 不成功: -1   没有转换的数据 0
    53. //
    54. //第三个  
    55. //原型: in_addr_t inet_addr(const char *cp);
    56. //参数 ;cp :十进制点分形式的ip字符串
    57. //返回值:网络字节序
    58. //
    59. //
    60. //第二个 
    61. //原型: const char *inet_ntop(int af ,const void src,char *dsr socklen_t size)
    62. //参数: af AF_IENT
    63. // src 要转化的网络字符串
    64. // dsr : 转化完的字符串
    65. // size dsr的空间大小
    66. //返回值:转换完的字符串
    67. //
    68. int main(int argc,char *argv[])
    69. {
    70. char *str="192.168.1.101";
    71. unsigned int net_order=0;
    72. //1.inet_pton() 函数 主机字节序的字符串 转换为 网络字节序的数值
    73. int res =inet_pton(AF_INET,str,&net_order);
    74. if(res <0)
    75. {
    76. perror("inet_pton error\n");
    77. return -1;
    78. }
    79. printf("res =%d inet_pton= %u\n",res,net_order);
    80. //3.inet_addr() 函数 主机字节序的字符串 转换为 网络字节序的数值
    81. in_addr_t netorder1 = inet_addr(str);
    82. printf("netorder = %u\n",netorder1);
    83. //2.inet_ntop() 函数 网络字节序的数值 转换为 主机字节序的字符串
    84. char ip[20]="";
    85. const char* ipstr = inet_ntop(AF_INET,&net_order,ip,sizeof(ip));
    86. printf("host ip = %s\n",ip);
    87. printf("ipstr =%s \n",ipstr);
    88. return 0;
    89. }

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

    代码:

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:网络编程
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. //查看数据在内存中的存储
    40. //网络字节序 是大端存储的字节序, 是在两个电脑传输的时候用的东西
    41. //主机字节序 是小端存储的字节序  是在自己的一个电脑上传输数据的东西
    42. int main(int argc,char *argv[])
    43. {
    44. int num =0x01020304; //主机字节序  数据的存储  也叫小端存储
    45. char *p=(char *)# //p 指向低地址
    46. int i;
    47. //真理 验证
    48. for(i=0;i<4;i++)
    49. {
    50. printf("%p %#x\n",p,*p); //%#x 十六进制的输出 
    51. p++;
    52. }
    53. return 0;
    54. }

    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.打包 与 解包 的过程

    代码:

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:socket 编程接口  是一种特殊的文件描述符号,并不限于TCP/IP 协议
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. #include
    42. //struct sockaddr_in
    43. //1.
    44. //通用的网络编程接口: socket  位于会话层 和传输层 之间
    45. //三种套接字 的类型
    46. //SOCK_STREAM 流式套接字  TCP
    47. // 数据报的套接字 UTP
    48. // _sockaddr_in
    49. int main(int argc,char *argv[])
    50. {
    51. if(argc <3)//参数判断
    52. {
    53. perror("argc error\n");
    54. return -1;
    55. }
    56. //打包
    57. //----------------------------
    58. struct sockaddr_in saddr ={0};
    59. saddr.sin_family=AF_INET; //IPV4 协议族
    60. saddr.sin_addr.s_addr = inet_addr(argv[1]);//主机字节序 转换 网络字节序
    61. saddr.sin_port = htons(atoi(argv[2])); // 端口号 字符串转换为主机字节序的整形 再次转化为 网络字节序的数字
    62. //解包
    63. //-------------------------------
    64. printf("sever port = %d\n",ntohs(saddr.sin_port));
    65. char ip[20]="";
    66. printf("server ip =%s \n",inet_ntop(AF_INET,&saddr.sin_addr.s_addr ,ip,sizeof(ip)));
    67. return 0;
    68. }

    25.函数;

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

    代码:

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. #include
    42. #include
    43. //1.gethostname: 获取本主机的名称
    44. //2.gethostbyname: 通过域名www.baidu.com  获得主机名
    45. //3.sethostname 设置主机名 
    46. int main()
    47. {
    48. /*
    49. char hostname1[100]="student-machine";
    50. if(!sethostname(hostname1,strlen(hostname1))) //设置主机名字
    51. {
    52. printf("set host = %s \n ",hostname1);
    53. }
    54. else
    55. {
    56. perror("set host error\n");
    57. return -2;
    58. }
    59. */
    60. char hostname[200]="";
    61. if(!gethostname(hostname,sizeof(hostname))) //获取主机名字
    62. {
    63. printf("hostname = %s \n",hostname);
    64. }
    65. else
    66. {
    67. printf("gethostname error\n");
    68. return -1;
    69. }
    70. //通过域名获取主机名字  
    71. char *str="www.baidu.com";
    72. struct hostent *host = gethostbyname(str);
    73. if(host ==NULL)
    74. {
    75. perror("gethostbyname error\n");
    76. }
    77. else
    78. printf("host name is %s\n",host->h_name);
    79. //输出别名
    80. while(*host->h_aliases !=NULL) //-> . [] 成员运算符  优先级很强
    81. {
    82. printf("aliases =%s \n",*host->h_aliases);
    83. host->h_aliases++; //二级指针可以移位置
    84. }
    85. //获取地址列表 
    86. char ip[100]="";
    87. while(*host->h_addr_list!=NULL)
    88. {
    89. printf("list : %s \n",inet_ntop(AF_INET,*host->h_addr_list,ip,sizeof(ip)));
    90. host->h_addr_list++;//二级指针可以移位置
    91. }
    92. return 0;
    93. }

  • 相关阅读:
    【POJ No. 3264】区间最值差 Balanced Lineup
    WuThreat身份安全云-TVD每日漏洞情报-2023-09-25
    leetcode 13. Roman to Integer(罗马字母转数字)
    2016-2021年各省高考分数线
    【1-系统架构演进过程】
    基于MATLAB的无人机路径规划设计
    ZCMU--1431: Epic Game(C语言)
    点击微信公众号菜单发送图片
    深度解析大模型代码能力现状
    带头的循环双向链表的简单介绍
  • 原文地址:https://blog.csdn.net/she666666/article/details/126291418