Linux网络编程——预备知识

1.Socket

 1.1、socket是一个应用编程接口,是一种特殊的文件描述符(可对其执行IO操作,open、write、close)

  一个文件描述符指向一个套接字,该套接字内部由内核借助两个缓冲区实现。

 1.2、socket代表网络编程的一种资源

    1.3、socket的类型

    流式套接字(SOCK_STREAM):唯一对应TCP

      提供一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收,内置流量控制,避免数据流

           淹没慢的接收方,数据流被看作字节流,无长度限制。

    数据报套接字(SOCK_DGRAM):唯一对应UDP

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

    原始套接字(SOCK_RAM):对应多个协议,发送穿透了传输层

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

2、IP地址

 2.1、IP地址是Internet中主机的1标识

  — Internet中主机要与别的主机通信必须要有一个IP地址

  — IP地址为32位(IPV4),或128位(IPV6)

  — 每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由

   2.2、表示形式

  —常用点分形式,如196.128.1.2

  —32位整数

  特殊IP地址:

  —局域网IP:192.xxx.xxx.xxx   10.xxx.xxx.xxx

  —广播IP:xxx.xxx.xxx.255   255.255.255.255(全网广播)

  —组播IP:224.xxx.xxx.xxx  ~  239.xxx.xxx.xxx

3.端口号

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

  TCP 端口号与UDP端口号独立

  端口号一般由INAN(Internet assigned numbers authority)管理

  —众所周知端口:1--1023(1~255为众所周知端口,256~1023端口通常有UNIX系统占用)

  —注册端口:1024~50000

  —动态或私有端口: 50000~65535

网络里的通信是由 IP地址 + 端口号来决定的

4.字节序

4.1 主机字节序

  字节序是指 整数 在内存中保存的顺序,是指不同的CPU访问内存中的多字节数据时,存在大小端问题。

 (若CPU访问的是字符串,则不存在大小端问题。)

  主机字节序(host-byte)指的是处理器存储数据的字节顺序。

 eg:   0X 12345678   (0X 高位------低位)

  最常见的有两种:

  1.Little endian:将低序字节存储在起始地址——LE

  2.Big endian:将高序字节存储在起始地址  ——BE

 一般来说:

  X86 / ARM : 小端模式

    Powerpc / mips:大端模式

 1 #include <stdio.h>
 2 #include <arpa/inet.h>
 3  
 4 int main(){
 5  
 6                 unsigned long a = 0x12345678;
 7                 unsigned char *p = (unsigned char *)(&a);
 8  
 9                 printf("主机字节序:%0x    %0x   %0x   %0x
",  p[0], p[1], p[2], p[3]);
10  
11                 unsigned long b = htonl(a);  //将主机字节序转化成了网络字节序
12                 
13                 p = (unsigned char *)(&b);
14  
15                 printf("网络字节序:%0x    %0x   %0x   %0x
",  p[0], p[1], p[2], p[3]);
16                 return 0;
17         } 
18 ————————————————
19 源程序链接:https://blog.csdn.net/msdnwolaile/article/details/50727653
验证主机大小端

4.2  网络字节序

  网络字节序(network-byte)指的是网络编程时,存储数据的字节顺序。在网络编程时用到的IP地址和端口号都需要网络字节序。

  TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节

  与“主机字节序”相反,网络字节序将数据的重要部分保存在低地址,不重要的部分保存到高地址。

  由于不同机器采用的字节序大小端可能不同,所以在传输数据的过程中,中间需要一个标准化的数据格式即网络字节序。

  a的固有数据存储-------标准化--------转化成b的固有格式  ——>    a的主机字节序----------网络字节序 ---------b的主机字节序

  

4.3  转换函数

  可以通过一系列的函数实现主机字节序和网络字节序之间的转换。

  函数中的h表示主机host,n表示网络networ,l表示长整形long,s表示短整形short。

1 /****主机字节序--->网络字节序****/
2 uing16_t htons(uint16_t short);  
3 uint32_t htonl(uint32_t hostlong);   
4 
5 /****网络字节序---->主机字节序****/
6 uint16_t ntohs(uint16_t netshort);    
7 uint32_t ntohl(uint32_t netlong);     

  IP地址转换函数:

 1 #include <arpa/inet.h>
 2 
 3 in_addr_t inet_addr(const char *cp);
 4 //net_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE
 5 //特点:  1、仅适用于IPV4
 6 //           2、出错返回-1
 7 //           3、此函数不能用于255.255.255.255的转换
 8 
 9 int inet_pton(int af, const char *src, void *dst) ;
10 //参数:    af---地址协议族(AF_INST和AF_INET6)
11 //            src--是一个指针(填写点分形式的IP地址,IPV4)
12 //            dst--转换的结果给dst
13 //特点:   1、适应于IPV4和IPV6
14 //            2、能正确处理255.255.255.255的转换
15 //            
16 inet_ntop();
 1 #include <stdio.h>
 2 #include <arpa/inet.h>
 3  
 4 int main()
 5 {
 6         struct in_addr ipaddr;
 7         unsigned long addr = inet_addr("192.168.1.100");
 8         printf("addr = %u
", ntohl(addr));
 9  
10         ipaddr.s_addr = addr;
11         printf("%s
", inet_ntoa(ipaddr));      
12         return 0;       
13 }
14 ————————————————
15 源程序:
16 https://blog.csdn.net/msdnwolaile/article/details/50727653

结果:

原文地址:https://www.cnblogs.com/y4247464/p/12129398.html