[英]client server UDP connection between clients c#
I'm writing application which is based on UDP Hole Punching. 我正在写基于UDP打孔的应用程序。 I have a problem with establishing connection between clients.
我在建立客户端之间的连接时遇到问题。 After each client sends something to server and server responses to each other with their IPs, clients aren't able to send anything to each other.
在每个客户端向服务器发送一些内容以及服务器使用其IP相互响应之后,客户端将无法相互发送任何内容。 Am I missing anything?
我有什么想念的吗? Or my understanding of UDP Hole Punching is wrong?
还是我对UDP打孔的理解是错误的? Yes, I've external IP for PC where server is.
是的,我有服务器所在的PC的外部IP。
server code : 服务器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
IPAddress IP = IPAddress.Parse("xx.xx.xx.xxx");
IPEndPoint localEP = new IPEndPoint(IP, 80);
UdpClient server = new UdpClient();
server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
server.ExclusiveAddressUse = false;
server.Client.Bind(localEP);
IPEndPoint temp;
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 80);
Console.WriteLine("Dane servera : " + localEP);
byte[] buffer = server.Receive(ref remoteEP);
Console.WriteLine("Otrzymano dane od : " + remoteEP + " o treści " + Encoding.ASCII.GetString(buffer));
temp = remoteEP;
remoteEP = new IPEndPoint(IPAddress.Any, 80);
byte[] buffer2 = server.Receive(ref remoteEP);
Console.WriteLine("Otrzymano dane od : " + remoteEP + " o treści " + Encoding.ASCII.GetString(buffer2));
byte[] response = Encoding.ASCII.GetBytes(temp.ToString());
server.Send(response, response.Length, remoteEP);
byte[] response2 = Encoding.ASCII.GetBytes(remoteEP.ToString());
server.Send(response2, response2.Length,temp );
}
}
}
client 1: 客户1:
namespace ConsoleApplication1
{
class Program
{
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
static void Main(string[] args)
{
IPAddress IP = IPAddress.Parse("xx.xx.xx.xxx");
IPEndPoint localpt = new IPEndPoint(IP, 80);
UdpClient client = new UdpClient();
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
client.ExclusiveAddressUse = false;
string powitanie = "ASUS";
byte[] buffer = new byte[100];
buffer = Encoding.ASCII.GetBytes(powitanie);
// client.Connect(localpt);
client.Send(buffer, buffer.Length,localpt);
byte[] otrzymane = client.Receive(ref localpt);
Console.WriteLine("Odpowiedz servera : " + Encoding.ASCII.GetString(otrzymane));
Console.Read();
IPEndPoint TV = CreateIPEndPoint(Encoding.ASCII.GetString(otrzymane));
byte[] buffer2 = client.Receive(ref TV);
Console.WriteLine("Odpowiedz klienta : " + Encoding.ASCII.GetString(buffer2));
}
}
}
client 2: 客户2:
namespace ConsoleApplication1
{
class Program
{
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
static void Main(string[] args)
{
IPAddress IP = IPAddress.Parse("xx.xx.xx.xxx");
IPEndPoint localpt = new IPEndPoint(IP, 80);
UdpClient client = new UdpClient();
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
client.ExclusiveAddressUse = false;
string powitanie = "Samsung";
byte[] buffer = new byte[100];
buffer = Encoding.ASCII.GetBytes(powitanie);
// client.Connect(localpt);
client.Send(buffer, buffer.Length,localpt);
byte[] otrzymane = client.Receive(ref localpt);
Console.WriteLine("Odpowiedz servera : " + Encoding.ASCII.GetString(otrzymane));
Console.Read();
IPEndPoint TV = CreateIPEndPoint(Encoding.ASCII.GetString(otrzymane));
client.Send(buffer, buffer.Length, TV);
}
}
}
Without access to your exact environment and network, I am not convinced it will be possible to offer an answer with any confidence that it would be assured of addressing the issue. 如果无法访问您的确切环境和网络,我不相信有信心提供肯定会解决该问题的答案。 But here are something things to keep in mind:
但是,请记住以下几点:
SocketOptionName.ReuseAddress
, which is almost always wrong. SocketOptionName.ReuseAddress
,这几乎总是错误的。 It appears to me that only your server socket binds to an explicit address, so using this option probably wouldn't affect the outcome of the test (ie you still only have one socket on any given address, even if you are testing in a single machine). Finally, you ask in a comment (please put relevant information and questions in the question itself): "should I use udp.connect to the server and then udp.send between clients" . 最后,您在评论中提问(请在问题本身中放入相关信息和问题): “我应该使用udp.connect到服务器,然后在客户端之间使用udp.send” 。 The answer is "no".
答案是不”。 First of all, using
Connect()
on a UDP socket is merely a convenience; 首先,在UDP套接字上使用
Connect()
只是一种方便; UDP itself is connectionless, and so connecting a UDP socket is handled entirely within the framework. UDP本身是无连接的,因此连接UDP套接字的操作完全在框架内进行。 Second, in .NET when you "connect" a UDP socket, the framework will filter datagrams, restricting them to those received from the "connected" endpoint.
其次,在.NET中,当您“连接” UDP套接字时,框架将过滤数据报,并将其限制为从“已连接”端点接收到的数据报。 This is exactly the opposite of what you want with hole-punching;
这与您想要的打孔恰好相反。 ie you want to be able to receive datagrams from both the server and the other client.
也就是说,您希望能够从服务器和另一个客户端接收数据报。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.