コード例 #1
0
ファイル: Sender.cs プロジェクト: oufengfang/p2pcopy
        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;
                }
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);*/
            }
        }
コード例 #4
0
ファイル: Sender.cs プロジェクト: oufengfang/p2pcopy
        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);
        }
コード例 #5
0
ファイル: Sender.cs プロジェクト: oufengfang/p2pcopy
        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!");
        }
コード例 #6
0
 public static gboolean GetNextClock(PseudoTcpSocket sock, ref guint64 timeout)
 {
     return(sock.GetNextClock(ref timeout));
 }
コード例 #7
0
 public static void NotifyClock(PseudoTcpSocket sock)
 {
     sock.NotifyClock();
 }
コード例 #8
0
 public static gboolean NotifyPacket(PseudoTcpSocket sock, byte[] buffer, guint32 len)
 {
     return(sock.NotifyPacket(buffer, len));
 }
コード例 #9
0
 public static gint Recv(PseudoTcpSocket sock, byte[] buffer, size_t len)
 {
     return(sock.Recv(buffer, len));
 }
コード例 #10
0
 public static gint Send(PseudoTcpSocket sock, byte[] buffer, guint32 len)
 {
     return(sock.Send(buffer, len));
 }
コード例 #11
0
 public void Closed(PseudoTcpSocket sock, uint err, object data)
 {
     PLog.DEBUG("UdpCallbacks.Closed: err={0}", err);
 }
コード例 #12
0
        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);
        }
コード例 #13
0
        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();
            }
        }
コード例 #14
0
ファイル: Receiver.cs プロジェクト: oufengfang/p2pcopy
        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");
            }
        }