问题在下面。这是我当前的测试代码,它没有成功。
static void Main(string[] args)
{
if (args.Count() != 3)
{
Console.WriteLine("Bad args");
}
var ep = new IPEndPoint(IPAddress.Parse(args[0]), int.Parse(args[1]));
var lp = new IPEndPoint(IPAddress.Any, int.Parse(args[2]));
var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
s.Bind(lp);
var c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
c.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
c.Bind(lp);
Task.Run(() => { try { c.Connect(ep); } catch { } });
s.Listen(10);
var v = s.Accept();
v.Close();
}
如何做TCP打孔?我正在使用远程服务器进行测试。我正在运行wget local_public_ip:port/test
。我已经为端口80设置了路由器,所以它不需要打孔。我的代码有关联。现在我尝试其他端口,但我不知道如何打孔。
我所做的是(C#代码)
var l = new TcpListener(8090);
l.Start();
try { var o = new TcpClient(); o.Connect("myserverip", 123); }
catch(Exception ex) {}
var e = l.AcceptSocket();
Console.WriteLine(e.RemoteEndPoint.AddressFamily);
TcpClient(new System.Net.IPEndPoint(new System.Net.IPAddress(bytearray), port));
The requested address is not valid in its context
如何做TCP打孔?
我将使用http://www.bford.info/pub/net/p2pnat/index.html中详细介绍的“顺序穿孔技术”。同时连接和套接字重用似乎要简单得多。打孔不一定要同时做任何事情(无论如何,在分布式系统中这是一个毫无意义的概念)。
我已经实现了打孔。我的路由器好像不喜欢。Wireshark显示出的出站打孔SYN是正确的,但远程方无法接通我。我使用tcpview.exe验证所有端口,并禁用所有防火墙。一定是路由器问题。(它是一个奇怪的入侵路由器。)
class HolePunchingTest
{
IPEndPoint localEndPoint;
IPEndPoint remoteEndPoint;
bool useParallelAlgorithm;
public static void Run()
{
var ipHostEntry = Dns.GetHostEntry("REMOTE_HOST");
new HolePunchingTest()
{
localEndPoint = new IPEndPoint(IPAddress.Parse("LOCAL_IP"), 1234),
remoteEndPoint = new IPEndPoint(ipHostEntry.AddressList.First().Address, 1235),
useParallelAlgorithm = true,
}.RunImpl();
}
void RunImpl()
{
if (useParallelAlgorithm)
{
Parallel.Invoke(() =>
{
while (true)
{
PunchHole();
}
},
() => RunServer());
}
else
{
PunchHole();
RunServer();
}
}
void PunchHole()
{
Console.WriteLine("Punching hole...");
using (var punchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
EnableReuseAddress(punchSocket);
punchSocket.Bind(localEndPoint);
try
{
punchSocket.Connect(remoteEndPoint);
Debug.Assert(false);
}
catch (SocketException socketException)
{
Console.WriteLine("Punching hole: " + socketException.SocketErrorCode);
Debug.Assert(socketException.SocketErrorCode == SocketError.TimedOut || socketException.SocketErrorCode == SocketError.ConnectionRefused);
}
}
Console.WriteLine("Hole punch completed.");
}
void RunServer()
{
using (var listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
EnableReuseAddress(listeningSocket);
listeningSocket.Bind(localEndPoint);
listeningSocket.Listen(0);
while (true)
{
var connectionSocket = listeningSocket.Accept();
Task.Run(() => ProcessConnection(connectionSocket));
}
}
}
void ProcessConnection(Socket connectionSocket)
{
Console.WriteLine("Socket accepted.");
using (connectionSocket)
{
connectionSocket.Shutdown(SocketShutdown.Both);
}
Console.WriteLine("Socket shut down.");
}
void EnableReuseAddress(Socket socket)
{
if (useParallelAlgorithm)
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
}
您可以尝试useparallelalgorithory
的两个值。两者都应该管用。
此代码用于服务器。它会在本地NAT中打孔。然后,您可以使用允许选择本地端口的任何客户端从远程端进行连接。我使用了curl.exe
。显然,Windows上的telnet不支持绑定到端口。显然也不是。
使用TcpView或Process Explorer验证端口在两侧是否正确。您可以使用Wireshark验证数据包。设置类似tcp.port=1234
的筛选器。
当您“调用”来打孔时,您可以启用元组(your-ip,your-port,remote-ip,remote-port)进行通信。这意味着所有进一步的通信都必须使用那些值。所有套接字(入站或出站)必须使用这些确切的端口号。如果您不知道:传出连接也可以控制本地端口。这只是不常见。
我已经尝试TCP打孔一段时间了,论坛似乎对基于TCP的方法和C编程语言没有多大帮助。主要参考文献如下, 我的设置是 客户端A--NAT-A--Internet--NAT-B--Client B。 假设客户机A知道B的公共endpoint和私有endpoint,而B知道A的endpoint(我已经编写了一个服务器'S',用于在对等点之间交换endpoint信息),并且两个NAT都不对称,如果两个客户
我有一个服务器-客户端程序,它使用TCP连接进行通信。多个客户端可以同时连接到服务器。我想在这个系统上实现tcp打孔。 在客户端,它调用公共服务器来查找我的服务器的公共ip端口。然后连接到它。 编辑:我有另一个想法。就是打开一个新的端口,连接到公共服务器。主服务器端口将像往常一样监听传入连接。当客户端想要连接时,公共服务器会通过新的端口通知我的服务器。它将停止主端口侦听传入的连接,相反,它将连接到
如何验证 Email 地址是否有效 一般来说,你不能。有一些看起来合理的方法可以使用,但却没有办法检测地址 是否实际可以投递,如果没有实际尝试投递的话。 使用正则表达式: # Match basically blah@blah.blah if ( $addr =~ /^\S+\@\S+\.\S+$/ ) { print "Looks OK"; } 如果你干真活的话,可能希望看看 CPAN
null 如果或都不能通过TCP启动连接,我将如何管理这种情况?(使用UDP?) 如果在这种情况下TCP打孔不起作用,我可以发送UDP包吗?(UDP在传递方面是不可靠的,所以发送多个重复的数据包能保证传递吗?) 我通常知道穿孔是如何工作的,必须将两个客户端的endpoint相互提供给对方,以便它们都可以尝试发起连接。而且我也很了解纳特的 对于TCP漏洞打孔无效的较少见的情况,可以充当代理
pnpm monorepo 如何做到批量打包?
通过vite中rollup打包,如何对lodash做按需打包? 这两种写法在build时 第一种dist体积比第二种要大。都说是第一种写法是将整个lodash打包进了dist。我这里有一个疑问,rollup在build时不是会对代码做按需打包吗? rollup的树摇不会起作用吗? 假设整个项目只使用了一个throttle函数,也会将整个lodash打包到dist吗? 虽然lodash是 cjs规范