问题描述
有一台server有公网IP有一台基于symmeticNAT后的电脑。client1SERVER程序启动后监听UDP56565端口如果收到报,就往回发一条。client1程序启动后监听UPD56565端口,然后我又向服务器发送一个UDP报,服务器收到我的信息后知道我的外网地址和经过NAT转换过的端口,比如:202.52.112.5:5000向这个地址发报,为什么客户端收不到。反正就是,客户端向服务器发送报,服务器可以接收到,然后服务器根据得到的IP和端口反发,则客户端收不到。住:上个贴也没结,等这个问题解决了一起结贴。
解决方案
解决方案二:
使用56565端口往外发,可能是防火墙把发送包给拦截了
解决方案三:
复杂帮顶吧
解决方案四:
服务器上没安装额外防火墙,系统自带防火墙已经关了。
解决方案五:
按道理来说symmeticNAT后的机器只要先给SERVER发包,SERVER收到后立刻回包应该和Client1是能够通讯上的.不知道你的为什么?是不是你NAT后有多于1个的公网IP?
解决方案六:
对于symmeticNAT,打开的端口会变化,也就是在symmeticNAT后的机器A给Server发送包后,symmeticNAT打开的端口就会改变,所以此时外网发送到这端口的包就会被丢弃。在这种NAT上建立P2P通讯是很困难的。有的说用端口猜测,但也不容易成功。
解决方案七:
不会吧,SymmetricNAT虽然不能用于P2P(就是不能打洞吧),但是和公网主机通讯还是可以的,只要是他先发包.我估计是NAT前有多台主机都在用同一个端口发UDP数据SymmetricNAT:内网主机建立一个UDPsocket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,第一次发送时,NAT会为其分配一个(PublicIP-2,Port-2),以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2).如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,则Port-1和Port-2肯定不同,也就是说一定不能是PublicIP-1等于PublicIP-2且Port-1等于Port-2。此外,如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,否则即使他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机,这种NAT无法实现UDP-P2P通信。
解决方案八:
不知道楼主是如何回复侦听信息的,UDP能回复信息么?我感觉好像不行吧,试试用TCP形势的服务器侦听这样:Socketsock=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//创建一个Socket类Socketc=null;while(true){try{c=sock.Accept();//这个c发来信息后,就可以给客户端回复信息了,如果需要一直使用,可用一个实例保存这个SOCKET,这个SOCKET就是你和客户端通讯的东西喽!//信息接收完成后,再继续开始一个侦听,然后跳出循环}catch{}}
解决方案九:
我贴下代码,先贴服务器的这个运行在服务器上,有外网IP监听UPD报privatevoidStartListener(){int端口=56565;//设置端口UdpClientlistener=newUdpClient(端口);//使用UDP协议IPEndPointip=newIPEndPoint(IPAddress.Any,端口);//任意IP,while(true)//使用永真循环另其一直处于监听状态{byte[]bytes=listener.Receive(refip);string文本=Encoding.GetEncoding("gb2312").GetString(bytes,0,bytes.Length);//获得信息回应c1(ip.Address.ToString(),ip.Port);MessageBox.Show("[IP:"+ip.Address+"]"+"[端口"+ip.Port+"]以返回");}}
这个是服务器收到后,往客户端发的报(也就是问题所在,客户端收不到服务器的报)privatevoid回应c1(stringip,intdk){Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);IPAddressbroadcast=IPAddress.Parse(ip);byte[]sendbuf=Encoding.GetEncoding("gb2312").GetBytes("服务器与你取得联系了");IPEndPointep=newIPEndPoint(broadcast,Convert.ToInt32(dk));s.SendTo(sendbuf,ep);//发送信息}
解决方案十:
这个是客户端向服务器发报(服务器可以收到)Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//实例化Socket对象//IPIPAddressbroadcast=IPAddress.Parse(this.textBox1.Text.ToString());//转换要发送的数据byte[]sendbuf=Encoding.GetEncoding("gb2312").GetBytes(this.textBox2.Text.ToString());//IP和端口IPEndPointep=newIPEndPoint(broadcast,Convert.ToInt32(textBox3.Text));//发送信息s.SendTo(sendbuf,ep);
这里是客户端监听又服务器回发的报(收不到)UdpClientlistenerp=newUdpClient(56565);//使用UDP协议IPEndPointgroupEP=newIPEndPoint(IPAddress.Any,56565);//任意IP,try{while(true)//使用永真循环另其一直处于监听状态{byte[]bytes=listenerp.Receive(refgroupEP);string文本=Encoding.GetEncoding("gb2312").GetString(bytes,0,bytes.Length);//获得信息MessageBox.Show("SERVER回应:"+文本+":");}}catch(Exceptione){listenerp.Close();MessageBox.Show(e.ToString());}
解决方案十一:
引用6楼wdgphc的回复:
不会吧,SymmetricNAT虽然不能用于P2P(就是不能打洞吧),但是和公网主机通讯还是可以的,只要是他先发包.我估计是NAT前有多台主机都在用同一个端口发UDP数据
嗯,习惯思维,当成两个是在内肉了。分析楼主的代码:你是向Serve的56565端口发消息,但你本地绑定的端口不一定就是56565,所以当服务器回发的时候,数据到达NAT时,NAT就会把它转发到本地发送时绑定的端口,而不一定就是56565。//这个是客户端向服务器发报(服务器可以收到)Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//实例化Socket对象//IPIPAddressbroadcast=IPAddress.Parse(this.textBox1.Text.ToString());//转换要发送的数据byte[]sendbuf=Encoding.GetEncoding("gb2312").GetBytes(this.textBox2.Text.ToString());//IP和端口IPEndPointep=newIPEndPoint(broadcast,Convert.ToInt32(textBox3.Text));//发送信息s.SendTo(sendbuf,ep);s.Receive(buf);//应用这种形式来接收服务器的回应。而不是建的UdpClient.