【发布时间】:2019-01-28 02:14:05
【问题描述】:
我有一个向 UDP 客户端发送数据(服务器)的应用程序。只要我知道客户端的目标地址,它就可以在同一台计算机上完美运行,并且可以在 LAN 上运行。但是,当我通过 Internet 执行此操作时,它不再起作用,因为它没有目标计算机的地址。这是服务器代码:
public ServerSender(String address, Int32 port, int TTL)
{
m_Address = address;
m_Port = port;
m_TTL = TTL;
Init();
}
private Socket m_Socket;
private IPEndPoint m_EndPoint;
private String m_Address;
private Int32 m_Port;
private Int32 m_TTL;
private void Init()
{
IPAddress destAddr = IPAddress.Parse(m_Address);
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_EndPoint = new IPEndPoint(destAddr, m_Port);
}
public void SendBytes(Byte[] bytes)
{
m_Socket.SendTo(bytes, 0, bytes.Length, SocketFlags.None, m_EndPoint);
}
这里是客户端:
public void Connect(string strAddress, int port)
{
m_Address = IPAddress.Parse(strAddress);
m_Port = port;
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // Multicast Socket
m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
m_EndPoint = new IPEndPoint(m_Address, m_Port);
m_Socket.Bind(m_EndPoint);
m_Socket.Connect(m_EndPoint);
IsConnected = true;
this.DoRead();
}
private void DoRead()
{
try
{
m_Socket.BeginReceive(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), m_Socket);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
很明显,服务器需要监听远程连接,客户端需要连接到服务器。我认为我可以获取远程地址,然后在 SendBytes 方法中发送到远程端点。我尝试了许多不同的异步服务器示例,它们都会导致各种错误。是否有任何简单的方法可以更改此代码以允许它通过 Internet 连接到远程主机? 谢谢
【问题讨论】:
-
对于 UDP,没有建立连接。就协议而言,没有 UDP 连接之类的东西。
-
好的,如何找到远程地址?我知道它可以通过 UDPClient 完成,因为我有这样的应用程序在互联网上运行。这不能用套接字来完成吗?
-
视情况而定。假设您知道典型 wan 上可能发生的事情(例如 NATing 等):
-
和通过 Internet 一样。整个基础架构通常假定您的客户端发送初始数据包。对于 TCP,这是在连接建立期间隐式完成的。 UDP 没有这样做。客户端将第一个数据报发送到您的服务器 - 只需发送一个虚拟 dgram。 dgram 包含一个源套接字(IP 和端口),然后您可以使用它从您的服务器发回(源套接字可能不是您在客户端实际发送的套接字 - 这应该无关紧要)。
-
如果您想了解其背景,请阅读有关 NAT (en.m.wikipedia.org/wiki/Network_address_translation) 的信息。
标签: asynchronous udp client-server wan