又探内网穿透——穿透工具ngrok,frp

本文探讨了内网穿透工具如frp和ngrok的工作原理,指出其本质是数据中转,而非点对点的TCP穿透。在对称型NAT下,TCP内网穿透成功率低,而UDP穿透相对成熟。作者测试了Natapp并提及安全性与效率问题,强调目前的内网穿透方案大多不适合商用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搜索内网穿透,蹦出来一大堆的内网穿透工具,这不禁让我怀疑人生:已经有这么成熟的产品了,还研究内网穿透干啥?

事实证明,这些内网穿透的工具,从原理上看,一是用的开源代码FRP、NGROK包装的,然后就是走的公网服务器中转。

并不是我想要的TCP-P2P穿透通信。1

而且调研过程中发现一个非常令人失望的事情,如图:

可惜成功率不高

只不过是中转,有什么意义呢?

可见,目前比较成熟的内网穿透的FRP,尚且对P2P-TCP的成功率不高(可能原理上讲无法穿透对称型NAT),然后另一个小众的穿透工具的设计大佬直接就说了,穿透用的就是转发。

 

所以说对我而言,P2P 点对点的内网穿透,并不是这些穿透工具所实现的,虽然有开源的FRP、NGROK,但是都没有实现点对点的内网穿透。

同时,在纯粹的P2P网络研究论文来说,TCP的内网穿透也是难以实现的,因为对称型NAT的存在,使得P2P穿透几乎变成了不可能的事情。

所以,内网穿透的研究暂时告一段落,结论:UDP穿透是成熟可行的,已经试验通过。TCP穿透试验失败,尚不清楚原因。

无论是哪一种穿透,都无法穿透对称型NAT,虽然可以采用基于端口预测的方式来穿透,但是暂时看来这种想法只能存在与理论之中。

现阶段的两种方式:STUN/TURN就是点对点穿透和中转,中转为了应付对称型NAT。ICE方式大家都说好,找遍全网找不到相关文档,只找到一个15年前的官方文档,但是却又不说应用只说怎么编写。ICE真的有人用吗?GITHUB都没多少人关注。

网上的内网穿透工具,本质原理分为Frp和ngrok两种,这两种原理一句话来说,就是中转数据。

查阅frp文档发现,frp已经在研究点对点的TCP大数据穿透了,但是却有一个括号说成功率不高,令人失望,我也没时间去试验了,毕竟人家frp商业软件都说不行...(还是懒)

然后看了看国内比较多的内网穿透工具:

NATAPP

NAT123

小蚂蚁内网穿透

花生壳

FRP

哲西信科续断

https://www.jianshu.com/p/cdc446e51675

但要使用第三方的公网服务器就必须为第三方付费,并且这些服务都有各种各样的限制,此外,由于数据包会流经第三方,因此对数据安全也是一大隐患。

http://www.ngrok.cc/_book/start/frp_windows.html

https://github.com/fatedier/frp

https://developer.github.com/webhooks/configuring/

 

最后,附上我写的测试Natapp的测试代码:测试成功,公网程序和局域网程序实现TCP通信。(但是又有什么意义呢?这样的转发一个是安全问题,一个是效率问题,都是无法商用的)

/*
文件:server.c
PS:第一个连接上服务器的客户端,称为client1,第二个连接上服务器的客户端称为client2
这个服务器的功能是:
1:对于client1,它返回"first",并在client2连接上之后,将client2经过转换后的IP和port发给client1;
2:对于client2,它返回client1经过转换后的IP和port和自身的port,并在随后断开与他们的连接。
 */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <mysql/mysql.h>

#define MAXLINE 128
#define SERV_PORT 7788

//发生了致命错误,退出程序

void error_quit(const char *str) {
	fprintf(stderr, "%s", str);
	//如果设置了错误号,就输入出错原因
	if (errno != 0)
		fprintf(stderr, " : %s", strerror(errno));
	printf("\n");
	exit(1);
}

int main(void) {
	int res, cur_port;
	int connfd, firstfd, listenfd;
	int count = 0;
	char str_ip[MAXLINE] = {0}; //当前IP地址
	char str_ip1[MAXLINE] = {0}; //缓存IP地址1
	char cur_inf[MAXLINE] = {0}; //当前的连接信息[IP+port]
	char first_inf[MAXLINE] = {0}; //第一个链接的信息[IP+port]
	char buffer[MAXLINE] = {0}; //临时发送缓冲区
	struct sockaddr_in cliaddr;
	struct sockaddr_in servaddr;
	socklen_t clilen;
	int aport 
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值