2
C#에서 3 방향 UDP 구멍 펀칭 응용 프로그램을 작성하려고합니다. 내가 읽은 것부터, 그 단계는 다음과 같습니다.C# UDPClient는 모든 IP 주소를 받아들입니다.
- 는 피어 1은
- 피어 2는 서버에 연결 한 세부 사항
- 피어 2가 연결 1
피어 투 피어받을 서버
그것은 피어 1은 메시지를 수락하지 않습니다 것처럼 나에게 보이는
1은 피어를 연결에는 문제가 없다 서버가 아닌 다른 IP 주소.
아래의 코드는 상당히 기본이지만 잘못된 부분을 생각할 수 있습니다. 누군가가 도망 칠 수 있다면, 나는 감사 할 것입니다.
피어 1
static void Main(string[] args)
{
int command = 0;
Random r = new Random();
while (true)
{
UdpClient client = new UdpClient();
IPEndPoint serverEndpoint = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 8924);
client.Connect(serverEndpoint);
client.Send(BitConverter.GetBytes(command), 1);
Task.Run(() => {
byte[] data = client.Receive(ref serverEndpoint);
Console.WriteLine(ASCIIEncoding.ASCII.GetString(data));
Console.ReadLine();
});
Console.WriteLine("sleep");
Thread.Sleep(30000);
Console.WriteLine("resume");
}
}
피어 2
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("press enter to start");
Console.ReadLine();
UdpClient getDetailsClient = new UdpClient();
IPEndPoint getDetailsEndpoint = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 8924);
getDetailsClient.Connect(getDetailsEndpoint);
getDetailsClient.Send(BitConverter.GetBytes(1), 1);
byte[] details = getDetailsClient.Receive(ref getDetailsEndpoint);
byte[] bIp = new byte[15];
int port = BitConverter.ToInt32(details, 0);
Array.Copy(details, 4, bIp, 0, 15);
string Ip = ASCIIEncoding.ASCII.GetString(bIp).Trim();
Console.WriteLine($"Address: {Ip} \tPort: {port}");
UdpClient peerClient = new UdpClient();
IPEndPoint endpointClient = new IPEndPoint(IPAddress.Parse(Ip), port);
peerClient.Connect(endpointClient);
peerClient.Send(ASCIIEncoding.ASCII.GetBytes("test"), 4);
Console.ReadLine();
}
}
서버
static void Main(string[] args)
{
int port = 8924;
IPEndPoint remote = new IPEndPoint(IPAddress.Any, port);
byte command;
UdpClient server = new UdpClient(port);
while(true)
{
//Wait on connection from client
var data = server.Receive(ref remote);
//get command
command = data[0];
switch(command)
{
case (byte)0:
updateDatabase(ref server, ref remote);
break;
case (byte)1:
readDatabase(ref server, ref remote);
break;
default:
break;
}
}
}
private static void updateDatabase(ref UdpClient server, ref IPEndPoint remote)
{
Console.WriteLine("Write Command");
using (dbDataContext db = new dbDataContext())
{
ConnectionTB tb = db.ConnectionTBs
.Where(t => t.UniqueIdentifier.Trim().Equals("123456789"))
.Select(t => t)
.FirstOrDefault();
tb.Port = remote.Port;
tb.IPAddress = remote.Address.ToString();
tb.LastPing = DateTime.Now;
db.SubmitChanges();
server.Send(ASCIIEncoding.ASCII.GetBytes(remote.Address.ToString().PadRight(15)),15,remote);
}
}
private static void readDatabase(ref UdpClient server, ref IPEndPoint remote)
{
Console.WriteLine("Read Command");
using (dbDataContext db = new dbDataContext())
{
ConnectionTB p = db.ConnectionTBs
.Where(c => c.UniqueIdentifier.Trim().Equals("123456789"))
.Select(c => c)
.FirstOrDefault();
int port = p.Port.Value;
string ip = p.IPAddress.Trim();
byte[] data = new byte[19];
byte[] bPort = BitConverter.GetBytes(port);
byte[] bIp = ASCIIEncoding.ASCII.GetBytes(p.IPAddress.PadRight(15));
Array.Copy(bPort, 0, data, 0, 4);
Array.Copy(bIp, 0, data, 4, 15);
server.Send(data, 19, remote);
}
}
전에 본 적이 없기 때문에 물어볼 것입니다. IPAddress.Parse ("xxx.xxx.xxx.xxx") 란 무엇입니까? 실제로 엔드 포인트에 IP 주소를 어떻게 제공합니까? 나는 당신이 연결된 udp 소켓을 사용하고 있다는 사실을 중심으로이 문제가 발생한다고 생각합니다. –
@user_ABCD - 표준 IP 주소 형식 (예 : "192.168.1.1")의 문자열 표현으로 IPAddress 객체를 만듭니다. 내 서버의 실제 IP 주소를 지우려면 'x'를 사용했습니다. – Chico
HA, 바보 같은 날. 최선의 방법은 ip와 포트를 직접 연결 호출에 전달하는 것입니다. 그런 다음 client.Receive 호출 앞에 엔드 포인트를 작성하고 IPAddress.Any를 전달하십시오. –