采用TCP/IP协议的c#punch NAT网络

采用TCP/IP协议的c#punch NAT网络,c#,tcp,nat,hole-punching,C#,Tcp,Nat,Hole Punching,UDP网络的工作原理和工作原理。然而,当谈到TCP时,可能是我写错了什么,但我不是一个初学者,或者可能是我不懂什么 当然,我会缩短一点,我们假设我们已经有了与外部服务器的连接这样简单的东西:) 线程之间的数据包同步,以及它们的创建、排队、序列化、发送原始字节等等,我略过了,因为它是关于创建TCP套接字的元素,而不是工作原理 我们将为服务器使用TcpListener类 public void InitializeServer(IP地址,int端口) { 尝试 { //127.0.0.1仅接受本地连

UDP网络的工作原理和工作原理。然而,当谈到TCP时,可能是我写错了什么,但我不是一个初学者,或者可能是我不懂什么

当然,我会缩短一点,我们假设我们已经有了与外部服务器的连接这样简单的东西:) 线程之间的数据包同步,以及它们的创建、排队、序列化、发送原始字节等等,我略过了,因为它是关于创建TCP套接字的元素,而不是工作原理

我们将为服务器使用TcpListener类

public void InitializeServer(IP地址,int端口)
{
尝试
{
//127.0.0.1仅接受本地连接,0.0.0.0对整个internet连接开放
侦听器=新的TcpListener(地址、端口);
socket=listener.Server;
//启用NAT转换
listener.allownatraversal(true);
//开始侦听例如10个客户端请求。
listener.Start(listenQueue);
Log($“[L{socket.LocalEndPoint}]服务器启动…”,EDebugLvl.Log);
OnServerInitialize(true);
//进入监听循环。
惊吓者();
}
捕获(SocketException e)
{
LogError($“SocketException:{e}”,EDebugLvl.Error);
OnServerInitialize(false);
}
}
我们开始倾听

private-void-istener()
{
Debug.Log(“\n正在等待连接…”);
beginacepttcpclient(AcceptCallback,listener);
}
当服务器接收到连接时,我们创建一个新的套接字

private void AcceptCallback(IAsyncResult ar)
{
TcpListener服务器=(TcpListener)ar.AsyncState;
TcpClient newClient=null;
尝试
{
newClient=server.endAcceptCpcClient(ar);
}
捕获(例外e)
{
LogError(例如ToString());
}
if(newClient!=null&&newClient.Connected)
{
//...
client.StartRead();
}
//环路
惊吓者();
}
我们在客户端创建一个新套接字并尝试建立连接

public void Connect(IPEndPoint remote,IPEndPoint bind=null,bool reuseAddress=false)
{
if(bind==null)
{
client=新的TcpClient();
}
其他的
{
客户机=新的TCP客户机(绑定);
}
socket=client.client;
如果(穿着)
{
socket.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.ReuseAddress,ReuseAddress);
//它向我抛出了一个错误选项,因此我对此进行了评论。
//socket.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.ReuseUnicastPort,reuseAddress);
}
client.BeginConnect(remote.Address、remote.Port、ConnectCallback、null);
}
连接工作时没有任何问题和数据传输

不幸的是,正如我们所知,我们必须在连接到服务器时创建的相同地址和端口上启动一个新套接字侦听。我为每个客户都这样做

public void StartHost(客户端-服务器)
{
if(server!=null&&server.socket.Connected)
{
IPEndPoint localHost=(IPEndPoint)server.socket.LocalEndPoint;
初始化主机(localHost.Address,localHost.Port);
}
}
public void InitializeHost(IPAddress地址、int端口、bool重用=false)
{
尝试
{
侦听器=新的TcpListener(地址、端口);
socket=listener.Server;
如果(重复使用)
{
socket.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.ReuseAddress,true);
socket.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.ReuseUnicastPort,true);
}
//启用NAT转换
listener.allownatraversal(true);
//开始侦听例如10个客户端请求。
listener.Start(listenQueue);
Log($“\n[L{socket.LocalEndPoint}]主机启动…”,EDebugLvl.Log);
OnServerInitialize(true);
//进入监听循环。
惊吓者();
}
捕获(SocketException e)
{
LogError($“SocketException:{e}”,EDebugLvl.Error);
OnServerInitialize(false);
}
}
private-void-istener()
{
Debug.Log(“\n正在等待连接…”);
beginacepttcpclient(AcceptCallback,listener);
}
private void AcceptCallback(IAsyncResult ar)
{
TcpListener服务器=(TcpListener)ar.AsyncState;
TcpClient newClient=null;
尝试
{
newClient=server.endAcceptCpcClient(ar);
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
if(newClient!=null&&newClient.Connected)
{
//...
client.StartRead();
}
//环路
惊吓者();
}
所以,当他们到处写的时候。。。客户端“B”向想要建立连接的服务器发送数据包,服务器向客户端“a”发送关于客户端“B”的信息,反之亦然

然后他们俩都试着用c