Linux网络编程——预备知识

jackalwb 2020-01-01

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:大端模式

#include <stdio.h>
#include <arpa/inet.h>
 
int main(){
 
                unsigned long a = 0x12345678;
                unsigned char *p = (unsigned char *)(&a);
 
                printf("主机字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);
 
                unsigned long b = htonl(a);  //将主机字节序转化成了网络字节序
                
                p = (unsigned char *)(&b);
 
                printf("网络字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);
                return 0;
        } 
————————————————
源程序链接:https://blog.csdn.net/msdnwolaile/article/details/50727653

验证主机大小端

4.2  网络字节序

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

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

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

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

  

4.3  转换函数

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

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

/****主机字节序--->网络字节序****/
uing16_t htons(uint16_t short);  
uint32_t htonl(uint32_t hostlong);   

/****网络字节序---->主机字节序****/
uint16_t ntohs(uint16_t netshort);    
uint32_t ntohl(uint32_t netlong);

IP地址转换函数:

#include <arpa/inet.h>

in_addr_t inet_addr(const char *cp);
//net_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE
//特点:  1、仅适用于IPV4
//           2、出错返回-1
//           3、此函数不能用于255.255.255.255的转换

int inet_pton(int af, const char *src, void *dst) ;
//参数:    af---地址协议族(AF_INST和AF_INET6)
//            src--是一个指针(填写点分形式的IP地址,IPV4)
//            dst--转换的结果给dst
//特点:   1、适应于IPV4和IPV6
//            2、能正确处理255.255.255.255的转换
//            
inet_ntop();
#include <stdio.h>
#include <arpa/inet.h>
 
int main()
{
        struct in_addr ipaddr;
        unsigned long addr = inet_addr("192.168.1.100");
        printf("addr = %u\n", ntohl(addr));
 
        ipaddr.s_addr = addr;
        printf("%s\n", inet_ntoa(ipaddr));      
        return 0;       
}
————————————————
源程序:
https://blog.csdn.net/msdnwolaile/article/details/50727653

结果:

Linux网络编程——预备知识

相关推荐