zoukankan      html  css  js  c++  java
  • Bridge transpor

    前言:

    之前在学校时老师经常发一些文件让我们下课学习,我们宿舍经常派一个代表下载了回来共享给其他人,为了方便宿舍间文件的共享,就有了Bridge transpor该项目的研究。

    项目简介:

    该项目是为了实现任意两台主机之间的文件下载,确保从一个指定的主机上下载指定的文件,也可以将自己的文件提供给别人下载。主要分为客户端和服务端两大模块。

    客户端:

    1、查看网络中的共享主机(向网络中广播配对请求)

    2、选择一个主机获取文件列表(向指定主机发送获取列表请求)

    3、下载指定文件(向指定主机发送下载指定文件请求)

    服务端:对客户端的请求作出正确的响应并提供服即可。

    详细设计:

    客户端:

    1.查看网络中的共享主机;

    (1)获取网卡信息(主机ip+mask),进而得到局域网中的所有ip地址列表 ;

    (2)对在线主机创建线程进行配对;

    (3)等待所有线程主机配对完成,判断配对结果,并将配对成功的主机ip打印出来供用户选择;

    协议选择:

    udp协议自带局域网广播功能,但有可能丢包,为了加深对tcp协议的学习,同时也为了文件传输的安全问题,采用tcp协议进行通信。

    http协议比较常用并有一定的自定制功能,为了加深学习,选择http进行网络通信

    2.获取文件列表接口;

    (1)向服务端发送一个文件列表获取请求

    (2)得到响应之后,解析正文(文件名称)

    (3)打印服务端响应的文件名称列表供用户选择

    3.下载指定主机上的指定文件供下载

    (1)向服务端发送文件下载请求

    (2)得到相应结果,响应结果中的body正文就是文件数据

    (3)创建文件,将文件数据写入文件中,关闭文件

    下载文件过程中如果文件过大则采用分块传输。

    服务端:

    1.接收到主机配对请求,则作出200响应;

    2.接收到文件列表请求

    (1)检测获取指定共享目录下的文件信息;

    (2)将所有的文件名组织成为http响应正文;

    3.接收到指定文件下载请求

    (1)通过文件名检测文件是否存在;

    (2)检测文件是否是一个普通文件

    (3)打开文件读取文件数据作为http响应正文响应给客户端;

    代码模块设计:

    获取网卡信息模块:

    class AdapterUtil
    {
    public:
    	static bool GetAllAdapter(std::vector<Adapter>*list)//获取网卡信息,返回信息数组
                    PIP_ADAPTER_INFO p_adapters = new IP_ADAPTER_INFO();
    		uint64_t all_adapter_size = sizeof(IP_ADAPTER_INFO);
    		//GetAdaptersInfo()是win下获取网卡信息的接口---网卡信息有可能有多个,因此传入一个指针
    		//因为空间不足,因此有一个输出型参数,用于向用户返回所有的网卡信息空间大小。
    		int ret = GetAdaptersInfo(p_adapters, (PULONG)&all_adapter_size);
    		if (ret == ERROR_BUFFER_OVERFLOW)//这个错误表示缓冲区空间不足
    		{
    			//重新给指针申请空间
    			delete p_adapters;
    			p_adapters = (PIP_ADAPTER_INFO)new BYTE[all_adapter_size];
    			GetAdaptersInfo(p_adapters, (PULONG)&all_adapter_size);//重新获取网卡信息
    		}
    		while (p_adapters)
    		{
    			Adapter adapter;
    			inet_pton(AF_INET, p_adapters->IpAddressList.IpAddress.String,&adapter._ip_addr);//将一个点分十进制的ip地址转换为网络字节序的ip地址
    			inet_pton(AF_INET,p_adapters->IpAddressList.IpMask.String,&adapter._mask_addr);
    			if (adapter._ip_addr == 0)
    			{
    				p_adapters = p_adapters->Next;
    				continue;
    			}
    			list->push_back(adapter);
    			p_adapters = p_adapters->Next;
    		}
    		delete p_adapters;
    		return true;
    	}
    };
    

    客户端模块:

    class Client
    {
    public:
    	bool Start()
    	{
    		//客户端程序需要循环运行,因为下载文件不是只下载一次
    		//循环运行每次下载一个文件之后都会重新进行主机配对(不合理)
    		while (1)
    		{
    			GetOnlineHost();
    		}
    		return true;
    	}
    	//主机配对的线程入口函数
    	void HostPair(Host *host)
    	//获取在线主机
    	bool GetOnlineHost()
    	//获取文件列表
    	bool GetShareList(const std::string &host_ip)
    	//下载文件,若文件比较大,一次性下载较危险
    	bool RangeDownload(const std::string &host_ip, const std::string &filename)
    private:
    	std::vector<Host> _online_host;
    };
    

    服务端模块:

    class Server
    {
    public:
        bool Start()
        {
            //std::cout << "服务端已经接收到配对请求
    ";
            //添加针对客户端请求的处理方式对应关系
            _srv.Get("/hostpair", HostPair);
            _srv.Get("/list", ShareList);
            //.表示除
    或
    以外的任意字符  *表示匹配前面字符任意次
            _srv.Get("/download/.*", DownLoad);//正则表达式,将特殊字符以指定格式,表示具有关键特征的数据
            _srv.listen("0.0.0.0", P2P_PORT);
            return true;
        }
    private:
           //对客户端进行的配对请求做出200响应;
           static void HostPair(const httplib::Request &req, httplib::Response &rsp)
           //对客户端的 文件列表请求做出正确响应
           static void ShareList(const httplib::Request &req, httplib::Response &rsp)
           //对客户端的文件下载做出正确响应
           static void DownLoad(const httplib::Request &req, httplib::Response &rsp)
    private:
        httplib::Server _srv;
    };
    

    项目的技术点:

    多线程/boost库中的一些目录操作/网络传输/http协议/tcp协议/c++ STL

    项目的扩展点:

    1.跨网络间的文件传输

    2.断点续传

    点击查看源码:https://github.com/MissLiDailyStruggle/C_plus_plus/tree/master/Bridge%20transport

  • 相关阅读:
    linux设置永久别名
    网站架构
    c#: 判断Firefox是否安装
    似是故人来
    Python: re.sub()第二个参数
    Python: AES加密与解密
    c#: Noto Sans字体如何支持韩文
    Inno Setup安装程序单例运行
    朵朵的二维码
    Python: 浅淡Python中的属性(property)
  • 原文地址:https://www.cnblogs.com/nbsun/p/13255133.html
Copyright © 2011-2022 走看看