当前位置:C++技术网 > 精选软件 > Libuv服务器实现内网穿透(内网打洞)的功能实现

Libuv服务器实现内网穿透(内网打洞)的功能实现

更新时间:2017-06-28 11:32:05浏览次数:1+次

    两台局域网的计算机要想直接通信,是不行的。原因是因为两台计算机都工作在局域网,没有公网IP。任何一方都无法得到对方的IP而发起通信。局域网的IP是192.168.*.*这样的。每一个局域网都这样,不具备唯一性。
    那么我们如何让两台局域网的两个计算机实现通信呢?我们需要借助一台公网IP计算机来完成。具有公网IP的计算机充当中间人,两台局域网的计算机都可以向具备公网IP的计算机发起通信。这样的话,中间人就在中间转发双方的数据,这样就实现了内网穿透(内网打洞)。或者,中间人降低参与度,直接将双方的套接字信息共享给双方。比如中间人将连入的所有的计算机的联系方式都公布在公告栏里,这样所有的计算机都可以根据公告栏里的联系方式直接线下连接了。
     QQ通信方式是服务器转发数据的方式,这样服务器可以实现数据过滤控制,可以提供更多的服务,比如QQ好友服务。而直接公布联系方式的做法,服务器只是作为查询的工具,参与度很低,很难从中获利。
    我们这里介绍的就是QQ的模式,服务器中转数据实现内网穿透。实际上这种模式使用的太多太多了。各种远程控制软件、通信软件等等,都会使用的。
    我们使用libuv库来实现这个功能,非常简单,简单到难以置信。
    我们使用的主要代码,就用我之前分享的libuv服务端封装类来做。代码见《libuv服务器端包装类源代码分享》。
    我们自己提供一个main函数,代码如下:
int main()
{
    g_srv.setnewconnectcb(new_conn_cb);
    g_srv.Start("0.0.0.0", 6111);
    return 0;
}
    然后提供回调函数和全局服务端变量的代码如下:
CTcpServer g_srv;
void recv_cb(int client_id, const char* buf, int buf_size)
{
    //处理接受消息
    char* tmp = new char[buf_size*2];
    memcpy(tmp, buf, buf_size*2);
    
    if (client_id==1)
    {
        g_srv.send(2, (const char*)tmp, buf_size);
    }
    if (client_id==2)
    {
        g_srv.send(1, (const char*)tmp, buf_size);
    }
    delete[] tmp;
    tmp = 0;
}
void new_conn_cb(int client_id)
{
    //设置新连接接收数据回调函数
    g_srv.setrecvcb(client_id, recv_cb);
}
    我们在recv_cb函数中,根据客户端ID变量client_id来识别不同的客户端,我们这里只是做测试,就固定为1和2,也就是先后连接的两个客户端。然后进行交叉数据转发,即1发给2,2发给1。
    下面是实现的效果:
    Libuv服务器实现内网穿透(内网打洞)的功能实现