123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- using System;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.Security.Cryptography;
- using System.Threading;
- namespace UdPunching
- {
- internal static class PeerProgram
- {
- private static RSACryptoServiceProvider _serverRsa;
- private static RSACryptoServiceProvider _peerRsa;
- private static IPEndPoint _serverEndPoint;
- private static int packetSeq;
- private static Socket _peerSocket;
- private static void ProcessPacket(SocketAsyncEventArgs sae)
- {
- ++packetSeq;
- Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} from {sae.RemoteEndPoint}, BytesTransferred {sae.BytesTransferred}");
- var peerId = TransferCodec.ReadId(sae.Buffer);
- Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} peer id {peerId}");
- if (sae.RemoteEndPoint.IpEndPointEqualsTo(_serverEndPoint))
- {
- if (TransferCodec.InvalidPeerId == peerId)
- {
- Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} Server FAILURE");
- }
- else if (Guid.Empty == peerId)
- {
- var msgData = TransferCodec.DecodeData(_peerRsa, sae.Buffer);
- Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} data length {msgData.Length}");
- var msg = new ExchangeMessage(msgData);
- Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} flag {msg.Flags}");
- if (msg.Flags.HasFlag(ExchangeMessageFlags.EchoEndPoint)) Console.WriteLine($"Incoming packet#{packetSeq:0,000,000} **** echo endpoint {msg.PeerEndPoint}");
- }
- //TODO: handle server message
- }
- else
- {
- //TODO: handle peers message
- }
- }
- private static void DeadLoopKeepAlive()
- {
- var buf = new byte[7];// 1flag,1count,1section,4timestamp
- var msg = new ExchangeMessage();
- msg.Flags = ExchangeMessageFlags.PeerKeepAlive;
- while (true)
- {
- msg.PeerTimeStamp = DateTime.Now;
- msg.WriteToBuffer(buf);
- var encode = TransferCodec.Encode(_serverRsa, Properties.Settings.Default.PeerId, buf);
- Console.WriteLine($"Sending packet KeepAlive {msg.PeerTimeStamp}");
- _peerSocket.SendTo(encode, _serverEndPoint);
- Thread.Sleep(1000);
- }
- }
- private static void Main(string[] args)
- {
- Console.WriteLine("Init...");
- _serverRsa = new RSACryptoServiceProvider();
- _serverRsa.FromXmlString(File.ReadAllText("ServerPublicKey.txt"));
- _peerRsa = new RSACryptoServiceProvider();
- _peerRsa.FromXmlString(File.ReadAllText("PeerPrivateKey.txt"));
- _serverEndPoint = new IPEndPoint(IPAddress.Parse(Properties.Settings.Default.Host), Properties.Settings.Default.Port);
- _peerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- _peerSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
- Console.WriteLine($"Peer Bind on {_peerSocket.LocalEndPoint}");
- const int receiveBufferSize = 1500;
- var sae = new SocketAsyncEventArgs();
- sae.SetBuffer(new byte[receiveBufferSize], 0, receiveBufferSize);
- sae.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- Console.WriteLine($"Receive buffer:{receiveBufferSize}");
- void SaeOnCompleted(object sender, SocketAsyncEventArgs e)
- {
- if (e.SocketError == SocketError.Success)
- {
- try
- {
- ProcessPacket(sae);
- }
- catch (Exception exception)
- {
- Console.WriteLine(exception);
- }
- }
- else
- {
- Console.WriteLine($"ERROR:{e.SocketError}");
- }
- sae.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- if (false == _peerSocket.ReceiveFromAsync(sae)) SaeOnCompleted(null, null);
- }
- sae.Completed += SaeOnCompleted;
- if (false == _peerSocket.ReceiveFromAsync(sae))
- {
- SaeOnCompleted(null, null);
- }
- DeadLoopKeepAlive();
- }
- }
- }
|