C# UDP通信 外网回发数据包给内网问题
请教下各位大哥,昨天的问题已经解决了~今天的问题如下:
现在用C#开发了一个C/S架构的UDP通信程序,在内网IP:192.168.1.2放置了客户端,开启本地IP监听,经过路由器,向外网的服务器端发送消息。外网的服务器端具有公网IP:180.169.48.140,服务器端已经开启了监听。现在的情况是,内网客户端发出去的数据包,外网服务器端能够收到,但是要求服务器端收到数据之后给出一个回复,并返回至内网客户端。现在的问题就在于,内网的客户端收不到回来的数据,主要集中有以下几个疑惑,请各位大哥指导~
1、外网的服务器如何获取内网客户端发出去的数据包,在经过路由器中转之后,对外的IP地址和端口?
2、如何在服务器端开启多端口监听?
3、服务器端如何发送数据回来,到达路由器之后,回到客户端?
相关代码如下:
IPEndPoint address = new IPEndPoint(IPAddress.Any, int.Parse("4321"));//client
//窗体初始化的时候开始监听UDP端口,监听所有IP地址来的信息,这边有个问题就是如何监听所有端口,不知是否可行?
udp = new UdpClient(address);
Thread thread = new Thread(new ThreadStart(RecieveData));//开启线程接收数据
thread.Start();
MessageBox.Show("监听开启");
SendMessage("time" + "IP地址:" + IpArray[0]);//发送数据,这边原来的想法是把本地IP地址,例如192.168.1.2发出去,在服务器端做截取用于回发,但是外网发回数据的时候,需要知道内网的出口IP,所以就无效了……
以上为客户端开启监听部分的代码。
下面是客户端发送数据的代码:
private void SendMessage(string text)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IpAdd.Text), int.Parse("1234"));//server ipadd.text 目的IP 1234端口
UdpClient udptmp = new UdpClient();
byte[] buffer = Encoding.UTF8.GetBytes(text);
//这里必须要将IP地址传过去,否则会报错(实例化的时候要IP地址反而会有麻烦)
udptmp.Send(buffer, buffer.Length, remoteEndPoint);
}
服务器端监听开启的代码如下:
IPEndPoint address = new IPEndPoint(IPAddress.Any, int.Parse("1234"));//server
//窗体初始化的时候开始监听UDP端口
udp = new UdpClient(address);
// 启动接收线程
Thread thread = new Thread(new ThreadStart(RecieveData));
thread.Start();
MessageBox.Show("服务器监听已经开启!");
当服务器端收到数据的时候 :
void RecieveDataIn()
{
while (true)
{
// 如果没有使用多线程这里一定要判断是否收到数据,
// 否则在Receive的时候线程会被挂起(直到接收到UDP请求,程序才会继续执行),造成卡死的现象
// 但是我们这是又开了一个线程,所以不需要判断,所以CPU占用率不会至少50%。
// 这里的udp.Available是对应的udp端口所获取的数据的总大小,与TCP方式不同(TCP是当前请求发送数据的大小)
if (udpIn.Available > 0)
{
IPEndPoint ipEndPoint = null;
byte[] buffer = udpIn.Receive(ref ipEndPoint);
string text = Encoding.UTF8.GetString(buffer);
SetTextIn(text);//显示数据
SendMessageAgain("消息收到了");//向内网客户端发送消息确认
}}}
服务器端向客户端回发消息代码:
private void SendMessageAgain(string text)
{
IPEndPoint remoteEndPoint2 = new IPEndPoint(IPAddress.Parse(fromip), int.Parse("4321"));//client 这边的问题就在于,如何获取来源数据包的外网IP和端口,以便回发?
UdpClient udp2 = new UdpClient();
byte[] buffer = Encoding.UTF8.GetBytes(text);
//这里必须要将IP地址传过去,否则会报错(实例化的时候要IP地址反而会有麻烦)
udp2.Send(buffer, buffer.Length, remoteEndPoint2);
udp2.Close();
}
客户端的监听一直在持续,收到消息之后,将消息打印……