C++/QT知识点积累(一):与网络通信相关

   计算机网络--子网掩码、ip地址、mac地址、网关

https://blog.csdn.net/weixin_43803070/article/details/90370460

 (1)IP地址

  • 用于标识网络中每台设备的标识。IPV4 :用32位表示;IPV6:用128位表示。IP地址=网络地址+主机地址,比如    192.168.40.1   。 IP地址由两部分组成,分别是:网络标识(绿色字体)和主机标识(蓝色字体)。同一网段内的计算机网络部分相同,主机部分不同同时重复出现。IP地址具有了唯一性;
    • 路由器连接不同网段,负责不同网段之间的数据转发;
    • 交换机连接的是同一网段的计算机
    • 计算机通信之前,首先要判断目标IP地址和自己的IP地址是否在一个网段,这决定了数据链层的目标MAC地址是目标计算机的还是路由器接口的MAC地址。
    • 数据包的目标IP地址决定了数据包最终到达哪一个计算机,
    • 数据包的目标MAC地址决定了数据包下一跳由哪个设备接收,不一定是终点。
  • A:A类地址保留给政府机构,一个A类地址由1字节的网络地址和3字节的主机地址组成,网络地址最高位必须是0,地址范围是1.0.0.1-127.255.255.254,但是127网段被作为环回地址使用,所以可用的A类网络只有126 个,每个网络能容纳 16777216 个主机。A类地址的私有地址为: 10.0.0.0~10.255.255.255,默认子网掩码为 255.0.0.0
  • B:B类地址分配给中等规模的公司,一个B类IP地址由2字节的网络地址和2字节的主机地址组成,网络地址的最高位必须是10,地址范围是128.0.0.1-191.255.255.254,可用的B类网络有16384 个,每个网络能容纳 65534 个主机。B类地址的私有地址为: 172.16.0.0~172.31.255.255 ,默认子网掩码为 255.255.0.0
  • C: C类地址分配给任何需要的人,一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址、7的最高位必须是110.地址范围是192.0.0.1-223.255.255.254. C类网络可达 2097152 个,每个网络能容纳254个主机。C类地址的私有地址为:192.168.0.0~192.168.255.255,默认子网掩码为 255.255.255.0
  • D:D类地址用于组播,第一个字节以1110开始,它是一个专门保留的地址,指向特定的网络,目前这一类地址被用在多点广播中。多点广播地址用来一次寻找一组计算机,它标识共享同一协议的一组计算机,地址范围是 224.0.0.1~239.255.255.254 
  • E:E类地址用于实验,E类地址不分网络地址和主机地址,它的第1字节的前五位固定为11110,地址范围是240.0.0.1~255.255.255.254

 (2)MAC地址

  • MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址、硬件地址,用来定义网络设备的位置。在OSI模型中,第三层网络层负责 IP地址,第二层数据链路层则负责 MAC地址。因此一个主机会有一个MAC地址,而每个网络位置会有一个专属于它的IP地址。
  • MAC地址是网卡决定的,是固定的,所有设备的MAC地址都是全球唯一的。MAC地址是网卡出厂时设定的,是固定的(但可以通过在设备管理器中或注册表等方式修改,同一网段内的MAC地址必须唯一)。MAC地址采用十六进制数表示,长度是6个字节(48位),分为前24位和后24位。

(3)网关

  • 网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。
  • 网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。

(4)子网掩码

  • 子网掩码(subnet mask)又叫网络掩码、地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。
  • 子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码作用是将某个IP地址划分成网络地址和主机地址两部分,子网掩码是一个32位地址,用于屏蔽IP地址的一部分以区别网络标识和主机标识,并说明该IP地址是在局域网上,还是在远程网上
    • A类地址的子网掩码是255.0.0.0,
    • B类地址的子网掩码是255.255.0.0 ,
    • C类地址的子网掩码是255.255.255.0
  • IP地址是以网络号和主机号来标示网络上的主机的,我们把网络号相同的主机称之为本地网络,网络号不相同的主机称之为远程网络主机,本地网络中的主机可以直接相互通信;远程网络中的主机要相互通信必须通过本地网关(Gateway)来传递转发数据。
  • 子网掩码的概念及作用
    • 子网掩码(Subnet Mask)必须结合IP地址一起对应使用。只有通过子网掩码,才能表明一台主机所在的子网与其他子网的关系,使网络正常工作。
    • 子网掩码和IP地址做“与”运算,分离出IP地址中的网络地址和主机地址,用于判断该IP地址是在本地网络上,还是在远程网络网上。
    • 子网掩码还用于将网络进一步划分为若干子网,以避免主机过多而拥堵或过少而IP浪费。
       

C++/QT知识点积累(一):与网络通信相关_第1张图片

  • 子网掩码的表示方法 

    • 点分十进制表示法:二进制转换十进制,每8位用点号隔开

子网掩码二进制11111111.11111111.11111111.00000000,表示为255.255.255.0

  • CIDR斜线记 

IP地址/n
例1:192.168.1.100/24,其子网掩码表示为255.255.255.0,二进制表示为11111111.11111111.11111111.00000000
例2:172.16.198.12/20,其子网掩码表示为255.255.240.0,二进制表示为11111111.11111111.11110000.00000000
不难发现,例1中共有24个1,例2中共有20个1,所以n是这么来的。运营商ISP常用这样的方法给客户分配IP地址。

  • 子网掩码可以分离出IP地址中的网络地址和主机地址,那为什么要分离呢?因为两台主机要通信,首先要判断是否处于同一网段,即网络地址是否相同。如果相同,那么可以把数据包直接发送到目标主机,否则就需要路由网关将数据包转发送到目的地。
    • A主机要与B主机通信,A和B各自的IP地址与A主机的子网掩码进行“与”(And)运算,看得出的结果:
      • 如果结果相同,则说明这两台主机是处于同一个网段,这样A可以通过ARP广播发现B的MAC地址,B也可以发现A的MAC地址来实现正常通信。
      • 如果结果不同,ARP广播会在本地网关终结,这时候A会把发给B的数据包先发给本地网关,网关再根据B主机的IP地址来查询路由表,再将数据包继续传递转发,最终送达到目的地B。
      • 计算机的网关(Gateway)就是到其他网段的出口,也就是路由器接口IP地址。路由器接口使用的IP地址可以是本网段中任何一个地址,不过通常使用该网段的第一个可用的地址或最后一个可用的地址,这是为了尽可能避免和本网段中的主机地址冲突。

 


 intet_addr()

  • 函数原型:
    • int_add_t inet_addr(const char *cp)
  • 输入参数:字符串,一个点分十进制的IP地址

  • 返回值:如果正确执行将返回一个无符号长整数型数。如果传入的字符串不是一个合法的IP地址,将返回INADDR_NONE。

  • 头文件:Winsock2.h (windows),arpa/inet.h (Linux)


    setsockopt/ getsockopt

  • 函数原型:
    • int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);
    • int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);
  • 输入参数:
    • sock:将要被设置或者获取选项的套接字。
    • level:选项所在的协议层。
    • optname:需要访问的选项名。
    • optval:
      • getsockopt(),指向返回选项值的缓冲。
      • setsockopt(),指向包含新选项值的缓冲。
    • optlen:
      • getsockopt(),作为入口参数时,选项值的最大长度。作为出口参数时,选项值的实际长度。
      • 对于setsockopt(),现选项的长度。
  • 返回值:成功执行时,返回0。失败返回-1,errno被设为以下的某个值  
    • EBADF:sock不是有效的文件描述词
    • EFAULT:optval指向的内存并非有效的进程空间
    • EINVAL:在调用setsockopt()时,optlen无效
    • ENOPROTOOPT:指定的协议层不能识别选项
    • ENOTSOCK:sock描述的不是套接字

 选项名称                      说明                数据类型
========================================================================
                    SOL_SOCKET
--------------------------------------------------------------------------------------------------------------------------------
SO_BROADCAST      允许发送广播数据            int
SO_DEBUG        允许调试                int
SO_DONTROUTE      不查找路由               int
SO_ERROR        获得套接字错误             int
SO_KEEPALIVE      保持连接                int
SO_LINGER        延迟关闭连接              struct linger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT       接收缓冲区下限             int
SO_SNDLOWAT       发送缓冲区下限             int
SO_RCVTIMEO       接收超时                struct timeval
SO_SNDTIMEO       发送超时                struct timeval
SO_REUSERADDR      允许重用本地地址和端口         int
SO_TYPE         获得套接字类型             int
SO_BSDCOMPAT      与BSD系统兼容              int

---------------------------------------------------------------------------------------------------------------------------------

sendto()

  • 函数原型:int sendto(int s, const void * msg, int len, unsigned int flags, const struct sockaddr * to, int tolen);
  • 输入参数:
    • s :已建好连线的socket,利用UDP协议则不需经过连线操作;
    • msg :指向欲连线的数据内容;
    • flags :一般设0
    • to :用来指定欲传送的网络地址
    • sockaddr :请参考bind()
    • tolen :sockaddr 的结果长度.
  • 输出参数:成功则返回实际传送出去的字符数;失败返回-1, 错误原因存于errno 中.
  • 错误代码:

EBADF 参数s 非法的socket 处理代码.
EFAULT 参数中有一指针指向无法存取的内存空间.
WNOTSOCK canshu s 为一文件描述词, 非socket.
EINTR 被信号所中断.
EAGAIN 此动作会令进程阻断, 但参数s 的soket 为补课阻断的.
ENOBUFS 系统的缓冲内存不足.
EINVAL 传给系统调用的参数不正确.

  • 头文件:
    • #include
    • #include

recvfrom()

  • 函数原型:int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from,int *fromlen);
  • 函数说明:recv()用来接收远程主机经指定的socket 传来的数据, 并把数据存到内存空间.
  • 输入参数:
    • s :已建好连线的socket,利用UDP协议则不需经过连线操作;
    • buf : 把数据存到由buf 指向的内存空间;
    • len :可接收数据的最大长度
    • flags: 一般设0
    • from :用来指定欲传送的网络地址
    • sockaddr:请参考bind().
  • 输出参数:成功则返回实际传送出去的字符数;失败返回-1, 错误原因存于errno 中.
  • 示例:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define PORT 2345
#define SERVER_IP “127.0.0.1”

main()
{
   int s, len;
   struct sockaddr_in addr;
   int addr_len = sizeof(struct sockaddr_in);
   char buffer[256];
   
   //建立socket
    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror(“socket”);
        exit(1);
    }
    //填写sockaddr_in
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;     //sin_family:表示协议簇,一般用AF_INET表示TCP/IP协议
    addr.sin_port = htons(PORT);                                    
    addr.sin_addr.s_addr = inet_addr(SERVER_IP);//sin_addr是联合体,可用多种方式表示IP
                                                //通常用无符号长整型数据来表示IP地址
    while(1)
    {
        bzero(buffer, sizeof(buffer));  //所有位致0
        //从标准输入设备取得字符串
        len = read(STDIN_FILENO, buffer, sizeof(buffer));
        //将字符串传送给server 端
        sendto(s, buffer, len, 0, &addr, addr_len);
        //接收server 端返回的字符串
        len = recvfrom(s, buffer, sizeof(buffer), 0, &addr, &addr_len);
        printf(“receive: %s”, buffer);
    }
}

你可能感兴趣的:(编程,qt,c++)