zoukankan      html  css  js  c++  java
  • VC++实现改变网关


    网关(Gateway)又称网间连接器、协议转换器。网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。在使用不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。大多数网关运行在OSI 7层协议的顶层--应用层。
    大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信  网关息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。也就是网络关卡。
      在OSI中,网关有两种:一种是面向连接的网关,一种是无连接的网关。当两个子网之间有一定距离时,往往将一个网关分成两半,中间用一条链路连接起来,我们称之为半网关。
      按照不同的分类标准,网关也有很多种。TCP/IP协议里的网关是最常用的,在这里我们所讲的“网关”均指TCP/IP协议下的网关。
      那么网关到底是什么呢?网关实质上是一个网络通向其他网络的IP地址。比如有网络A和网络B,网络A的IP地址范围为“192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0;网络B的IP地址范围为“192.168.2.1~192.168.2.254”,子网掩码为255.255.255.0。在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。而要实现这两个网络之间的通信,则必须通过网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机(如附图所示)。网络A向网络B转发数据包的过程。
      所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。那么这个IP地址是哪台机器的IP地址呢?网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
      在和 Novell NetWare 网络交互操作的上下文中,网关在 Windows 网络中使用的服务器信息块 (SMB) 协议以及NetWare网络使用的 NetWare 核心协议 (NCP) 之间起着桥梁的作用。网关也被称为 IP 路由器。




    请见代码

    #include <stdio.h>
    #include <windows.h>
    #include <Iphlpapi.h>
    
    #pragma comment(lib, "Iphlpapi.lib")
    #pragma comment(lib, "WS2_32.lib")
    
    
    PMIB_IPFORWARDTABLE MyGetIpForwardTable(BOOL bOrder);
    void MyFreeIpForwardTable(PMIB_IPFORWARDTABLE pIpRouteTab);
    void PrintIpForwardTable();
    
    int main()
    {
    	// 新网关地址
    	DWORD dwNewGateway = ::inet_addr("192.168.0.1");
    
    	// 在表中查找我们想要的入口。默认网关的目的地址为0.0.0.0
    	PMIB_IPFORWARDTABLE pIpRouteTable = MyGetIpForwardTable(TRUE);
    	PMIB_IPFORWARDROW pRow = NULL;
    	if(pIpRouteTable != NULL)
    	{
    		for(DWORD i=0; i<pIpRouteTable->dwNumEntries; i++)
    		{
    			if(pIpRouteTable->table[i].dwForwardDest == 0)	// 找到了默认网关
    			{
    				// 申请内存来保存这个入口。
    				// 这比自己填充MIB_IPFORWARDROW结构简单许多,我们仅需要改变网关地址
    				if(pRow == NULL)
    				{
    					pRow = (PMIB_IPFORWARDROW)::GlobalAlloc(GPTR, sizeof(MIB_IPFORWARDROW));
    					memcpy(pRow, &pIpRouteTable->table[i], sizeof(MIB_IPFORWARDROW));
    				}
    
    				// 删除旧的默认网关入口
    				if(::DeleteIpForwardEntry(&pIpRouteTable->table[i]) != ERROR_SUCCESS)
    				{
    					printf("Could not delete old gateway \n");
    					exit(1);
    				}
    			}
    		}
    		MyFreeIpForwardTable(pIpRouteTable);
    	}
    
    	if(pRow != NULL)
    	{
    		// 设置dwForwardNextHop域为我们的新网关,所有其它的路由属性将和先前的相同
    		pRow->dwForwardNextHop = dwNewGateway;
    
    		// 为默认网关创建新的路由入口
    		if(::SetIpForwardEntry(pRow) == NO_ERROR)
    			printf(" Gateway changed successfully \n");
    		else
    			printf(" SetIpForwardEntry() failed \n");
    
    		::GlobalFree(pRow);
    	}
    
    	return 0;
    }
    
    PMIB_IPFORWARDTABLE MyGetIpForwardTable(BOOL bOrder)
    {
    	PMIB_IPFORWARDTABLE pIpRouteTab = NULL;
        DWORD dwActualSize = 0;
        
        // 查询所需缓冲区的大小
        if(::GetIpForwardTable(pIpRouteTab, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER)
    	{
            // 为MIB_IPFORWARDTABLE结构申请内存
            pIpRouteTab = (PMIB_IPFORWARDTABLE)::GlobalAlloc(GPTR, dwActualSize);
            // 获取路由表
    		if(::GetIpForwardTable(pIpRouteTab, &dwActualSize, bOrder) == NO_ERROR)
    			return pIpRouteTab;
    		::GlobalFree(pIpRouteTab);
        }
    	return NULL;
    }
    
    void MyFreeIpForwardTable(PMIB_IPFORWARDTABLE pIpRouteTab)
    {
    	if(pIpRouteTab != NULL)
    		::GlobalFree(pIpRouteTab);
    }







  • 相关阅读:
    有爱,有期待——开启囤货模式(一)
    我们都爱你,悠悠球少年
    三月随笔——漫长的等待
    奢侈的休闲度假时光——带着小样儿去三亚(三)
    这个夏天,飞到北纬18°去玩海——带着小样儿去三亚(二)
    一场说走就走的旅程——带着小样儿去三亚(一)
    获取URL的参数-详解如何获取(自己写的,实测有效)
    背景图自适应
    百家姓
    判断是手机端还是PC端的代码
  • 原文地址:https://www.cnblogs.com/new0801/p/6177675.html
Copyright © 2011-2022 走看看