static void ProcessNotifyClockQueue(PseudoTcpSocket conn, Queue notifyClockQueue) { PLog.DEBUG("Entering ProcessNotifyClockQueue with queue size={0}", notifyClockQueue.Count); if (notifyClockQueue.Count != 0) { PLog.DEBUG("...and head timestamp={0}, current time={1}", notifyClockQueue.Peek(), Environment.TickCount); } if (notifyClockQueue.Count == 0) { UdpCallbacks.AdjustClock(conn, notifyClockQueue); return; } bool keepChecking = true; while (keepChecking && notifyClockQueue.Count > 0) { int iTimestamp = (int)notifyClockQueue.Peek(); if (Environment.TickCount > iTimestamp) { SyncPseudoTcpSocket.NotifyClock(conn); notifyClockQueue.Dequeue(); } else { keepChecking = false; } } }
public bool Init( string externalAddr, int externalPort, string remoteAddr, int remotePort, PseudoTcpSocket pseudoSock, Socket underlyingSock, bool isSender, int nextTimeToSync) { this.externalAddr = externalAddr; this.externalPort = externalPort; this.remoteAddr = remoteAddr; this.remotePort = remotePort; this.pseudoSock = pseudoSock; this.underlyingSock = underlyingSock; udpc = new UdpClient(); udpc.Client = underlyingSock; udpc.Connect(new IPEndPoint(IPAddress.Parse(remoteAddr), remotePort)); endReceiveRemoteEP = new IPEndPoint(IPAddress.Any, 0); Console.WriteLine("After reusing existing sock:"); Console.WriteLine("UdpClient.Client.LocalEndPoint=" + udpc.Client.LocalEndPoint); Console.WriteLine("UdpClient.Client.RemoteEndPoint=" + udpc.Client.RemoteEndPoint); Console.WriteLine("underlyingSock.LocalEndPoint=" + underlyingSock.LocalEndPoint); if (TryNatTraversal(isSender, nextTimeToSync)) { BeginReceive(); return(true); } else { Console.WriteLine("NAT traversal failed"); return(false); } }
public static void AdjustClock(PseudoTcp.PseudoTcpSocket sock, Queue notifyClockQueue) { ulong timeout = 0; if (SyncPseudoTcpSocket.GetNextClock(sock, ref timeout)) { PLog.DEBUG("AdjustClock: GetNextClock={0}", timeout); uint now = PseudoTcpSocket.GetMonotonicTime(); if (now < timeout) { timeout -= now; } else { timeout = now - timeout; } //Console.WriteLine ("...original timeout={0}", timeout); //if (timeout > 900) // timeout = 100; /// Console.WriteLine ("Socket {0}: Adjusting clock to {1} ms", sock, timeout); notifyClockQueue.Enqueue(Environment.TickCount + (int)timeout); } else { PLog.DEBUG("AdjustClock: didnt get timeout"); /*left_closed = true; * * if (left_closed && right_closed) * g_main_loop_quit (mainloop);*/ } }
static int SendFragment(PseudoTcpSocket conn, byte[] buffer, int fragmentSize, Queue notifyClockQueue) { int sent; do { PLog.DEBUG("Trying to send {0} bytes", fragmentSize); sent = SyncPseudoTcpSocket.Send(conn, buffer, (uint)fragmentSize); if (sent == -1) { PLog.DEBUG("sent==-1 so processing notifyClockQueue"); ProcessNotifyClockQueue(conn, notifyClockQueue); } else { UdpCallbacks.AdjustClock(conn, notifyClockQueue); } UdpCallbacks.PollingSleep(sent, -1); } while (sent == -1); PLog.DEBUG("Tried sending fragment sized {0} with result {1}", fragmentSize, sent); return(sent); }
static internal void Run(PseudoTcpSocket conn, string file, bool bVerbose) { int ini = Environment.TickCount; Queue notifyClockQueue = new Queue(); using (FileStream fileReader = new FileStream(file, FileMode.Open, FileAccess.Read)) { long fileSize = new FileInfo(file).Length; byte[] ackBuffer = new byte[1]; PLog.DEBUG("Sending filename {0}", Path.GetFileName(file)); byte[] fileNameBytes = Encoding.UTF8.GetBytes(Path.GetFileName(file)); byte[] fileNameBytesLength = BitConverter.GetBytes(fileNameBytes.Length); PLog.DEBUG("Length of file name in bytes={0}", fileNameBytesLength); SyncPseudoTcpSocket.Send(conn, fileNameBytesLength, (uint)fileNameBytesLength.Length); SyncPseudoTcpSocket.Recv(conn, ackBuffer, 1); PLog.DEBUG("Sent filename length, ack={0}", ackBuffer [0]); SyncPseudoTcpSocket.Send(conn, fileNameBytes, (uint)fileNameBytes.Length); SyncPseudoTcpSocket.Recv(conn, ackBuffer, 1); PLog.DEBUG("Sent filename bytes {0}={1}, ack={2}", fileNameBytes, BitConverter.ToString(fileNameBytes), ackBuffer[0]); SyncPseudoTcpSocket.Send(conn, BitConverter.GetBytes(fileSize), 8); SyncPseudoTcpSocket.Recv(conn, ackBuffer, 1); PLog.DEBUG("Sent file size, ack={0}", ackBuffer [0]); byte[] buffer = new byte[512 * 1024]; long pos = 0; int i = 0; ConsoleProgress.Draw(i++, pos, fileSize, ini, Console.WindowWidth / 3); while (pos < fileSize) { ProcessNotifyClockQueue(conn, notifyClockQueue); int toSend = buffer.Length < (fileSize - pos) ? buffer.Length : (int)(fileSize - pos); PLog.DEBUG("File reading: pos={0}, fileSize={1}, toSend={2}", pos, fileSize, toSend); fileReader.Read(buffer, 0, toSend); int iteration = Environment.TickCount; int sent; int totalSent = 0; int fragmentSize = toSend; while (totalSent < toSend) { sent = SendFragment(conn, buffer, fragmentSize, notifyClockQueue); totalSent += sent; PLog.DEBUG("totalSent={0} sent={1} fragmentSize={2}", totalSent, sent, fragmentSize); if (sent < fragmentSize) { byte[] buffer2 = new byte[fragmentSize - sent]; Buffer.BlockCopy(buffer, sent, buffer2, 0, buffer2.Length); fragmentSize = buffer2.Length; buffer = buffer2; } } PLog.DEBUG("finished sending toSend={0}", toSend); pos += toSend; ConsoleProgress.Draw(i++, pos, fileSize, ini, Console.WindowWidth / 3); if (bVerbose) { Console.WriteLine(); Console.WriteLine("Current: {0} / s", SizeConverter.ConvertToSizeString(toSend / (Environment.TickCount - iteration) * 1000)); //Console.WriteLine("BandwidthMbps {0} mbps.", conn.GetPerformanceInfo().Probe.BandwidthMbps); //Console.WriteLine("RoundtripTime {0}.", conn.GetPerformanceInfo().Probe.RoundtripTime); //Console.WriteLine("SendMbps {0}.", conn.GetPerformanceInfo().Local.SendMbps); //Console.WriteLine("ReceiveMbps {0}.", conn.GetPerformanceInfo().Local.ReceiveMbps); } } } Console.WriteLine(); while (conn.priv.sbuf.data_length != 0) { Console.WriteLine("Waiting for buffered data to finish sending..."); for (int i = 0; i < 20; i++) { conn.NotifyClock(); Thread.Sleep(50); } } Console.WriteLine(); Console.WriteLine("Done!"); }
public static gboolean GetNextClock(PseudoTcpSocket sock, ref guint64 timeout) { return(sock.GetNextClock(ref timeout)); }
public static void NotifyClock(PseudoTcpSocket sock) { sock.NotifyClock(); }
public static gboolean NotifyPacket(PseudoTcpSocket sock, byte[] buffer, guint32 len) { return(sock.NotifyPacket(buffer, len)); }
public static gint Recv(PseudoTcpSocket sock, byte[] buffer, size_t len) { return(sock.Recv(buffer, len)); }
public static gint Send(PseudoTcpSocket sock, byte[] buffer, guint32 len) { return(sock.Send(buffer, len)); }
public void Closed(PseudoTcpSocket sock, uint err, object data) { PLog.DEBUG("UdpCallbacks.Closed: err={0}", err); }
static PseudoTcpSocket PeerConnect(string externalAddr, int externalPort, Socket socket, string remoteAddr, int remotePort, CommandLineArguments cla) { bool bConnected = false; int retry = 0; PseudoTcpSocket client = null; while (!bConnected) { try { Console.WriteLine("Getting internet time"); DateTime now = InternetTime.Get(); int nextTimeToSync = NextTime(now); int sleepTimeToSync = nextTimeToSync - now.Second; Console.WriteLine("[{0}] - Waiting {1} sec to sync with other peer", now.ToLongTimeString(), sleepTimeToSync); System.Threading.Thread.Sleep(sleepTimeToSync * 1000); PseudoTcpSocket.Callbacks cbs = new PseudoTcpSocket.Callbacks(); UdpCallbacks icbs = new UdpCallbacks(); cbs.WritePacket = icbs.WritePacket; cbs.PseudoTcpOpened = icbs.Opened; cbs.PseudoTcpWritable = icbs.Writable; cbs.PseudoTcpClosed = icbs.Closed; client = PseudoTcpSocket.Create(0, cbs); client.NotifyMtu(1496); // Per PseudoTcpTests bool success = icbs.Init(externalAddr, externalPort, remoteAddr, remotePort, client, socket, cla.Sender, nextTimeToSync); if (false == success) { continue; } PLog.DEBUG("Created PseudoTcpSocket"); Console.WriteLine("\r{0} - Trying to connect to {1}:{2}. ", retry++, remoteAddr, remotePort); if (cla.Sender) { PLog.DEBUG("Sender: calling PseudoTcpSocket.Connect"); client.Connect(); } int startTime = Environment.TickCount; while (false == bConnected) { Console.WriteLine("priv.state=={0}", client.priv.state); if (PseudoTcpSocket.PseudoTcpState.Values.TCP_ESTABLISHED == client.priv.state) { Console.WriteLine("Connected successfully to {0}:{1}", remoteAddr, remotePort); bConnected = true; } else { if (Environment.TickCount > startTime + Config.MAX_TCP_HANDSHAKE_TIME) { Console.WriteLine("5 secs timed out with priv.state={0}", client.priv.state); break; } else { Console.WriteLine("Waiting for TCP_ESTABLISHED..."); Thread.Sleep(500); } } } } catch (Exception e) { Console.WriteLine(e.Message.Replace(Environment.NewLine, ". ")); Console.WriteLine(e.StackTrace); Console.WriteLine("Inner exception=" + e.InnerException); } } return(client); }
static void Main(string[] args) { CommandLineArguments cla = CommandLineArguments.Parse(args); if (cla == null || (!cla.Sender && !cla.Receiver)) { CommandLineArguments.ShowUsage(); return; } string remoteIp; int remotePort; Socket socket = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); try { if (cla.LocalPort != -1) { Console.WriteLine("Using local port: {0}", cla.LocalPort); } else { cla.LocalPort = 0; } socket.Bind(new IPEndPoint(IPAddress.Any, cla.LocalPort)); P2pEndPoint p2pEndPoint = GetExternalEndPoint(socket); Console.WriteLine("p2pEndPoint external=" + p2pEndPoint.External); Console.WriteLine("p2pEndPoint internal=" + p2pEndPoint.Internal); if (p2pEndPoint == null) { return; } Console.WriteLine("Tell this to your peer: {0}", p2pEndPoint.External.ToString()); Console.WriteLine(); Console.WriteLine(); Console.Write("Enter the ip:port of your peer: "); string peer = Console.ReadLine(); if (string.IsNullOrEmpty(peer)) { Console.WriteLine("Invalid ip:port entered"); return; } // try again to connect to external to "reopen" port GetExternalEndPoint(socket); ParseRemoteAddr(peer, out remoteIp, out remotePort); PseudoTcpSocket connection = PeerConnect( p2pEndPoint.External.Address.ToString(), p2pEndPoint.External.Port, socket, remoteIp, remotePort, cla); Console.WriteLine("Called PeerConnect"); if (connection == null) { Console.WriteLine("Failed to establish P2P conn to {0}", remoteIp); return; } try { if (args[0] == "sender") { Sender.Run(connection, cla.File, cla.Verbose); } else { Receiver.Run(connection); } } finally { connection.Close(false); } } finally { socket.Close(); } }
static internal void Run(PseudoTcpSocket conn) { PLog.DEBUG("In Receiver.Run"); int ini = Environment.TickCount; byte[] ackBuffer = new byte[1]; ackBuffer [0] = 1; long got = 0; byte[] fnlBytes = new byte[4]; do { got = SyncPseudoTcpSocket.Recv(conn, fnlBytes, 4); PLog.DEBUG("Reading filename length, got={0}", got); UdpCallbacks.PollingSleep(got, -1); } while (got == -1); SyncPseudoTcpSocket.Send(conn, ackBuffer, 1); uint fileNameLengthBytes = (uint)BitConverter.ToInt32(fnlBytes, 0); PLog.DEBUG("Got filename length=" + fileNameLengthBytes); byte[] fnBytes = new byte[fileNameLengthBytes]; do { got = SyncPseudoTcpSocket.Recv(conn, fnBytes, fileNameLengthBytes); PLog.DEBUG("Reading filename, got={0}", got); UdpCallbacks.PollingSleep(got, -1); } while (got == -1); SyncPseudoTcpSocket.Send(conn, ackBuffer, 1); PLog.DEBUG("filename bytes=" + BitConverter.ToString(fnBytes)); string fileName = System.Text.Encoding.UTF8.GetString(fnBytes); Console.WriteLine("Receiving file: {0}", fileName); byte[] fileSizeBytes = new byte[sizeof(long)]; do { got = SyncPseudoTcpSocket.Recv(conn, fileSizeBytes, (uint)fileSizeBytes.Length); PLog.DEBUG("Reading file size, got={0}", got); UdpCallbacks.PollingSleep(got, -1); } while (got == -1); SyncPseudoTcpSocket.Send(conn, ackBuffer, 1); long size = (long)BitConverter.ToInt64(fileSizeBytes, 0); Console.WriteLine("File size={0} bytes", size); byte[] buffer = new byte[4 * 1024 * 1024]; int i = 0; ConsoleProgress.Draw(i++, 0, size, ini, Console.WindowWidth / 2); using (FileStream fileStream = new FileStream(fileName, FileMode.Create)) { long len = 0; long read = 0; while (read < size) { do { PLog.DEBUG("{0} Reading file data... so far total read={1}", Environment.TickCount, read); len = SyncPseudoTcpSocket.Recv(conn, buffer, (uint)buffer.Length); UdpCallbacks.PollingSleep(len, -1); } while (len == -1); PLog.DEBUG("Read {0} bytes of file data", len); fileStream.Write(buffer, 0, (int)len); read += len; ConsoleProgress.Draw(i++, read, size, ini, Console.WindowWidth / 2); } double MB = (double)size * 8.0 / (1024.0 * 1024.0); double rxTime = (Environment.TickCount - ini) / 1000.0; Console.WriteLine(); Console.WriteLine("Receive time=" + rxTime + " secs"); Console.WriteLine("Av bandwidth=" + MB / rxTime + " Mbits/sec"); } }