예제 #1
0
        public override void SendMessage(PrimaryMessage message)
        {
            if (message.MessageType == PrimaryMessageType.FileTransportClientToServer)
            {
                var ftd = message.ClientData.GetSerializeAble <FileTransportData>();
                switch (ftd.Type)
                {
                case FileTransportType.WaitToGetPort:
                {
                    var task = FindTask(ftd.TransportID, ftd.SenderID);
                    task.State          = FileTransportState.WaitForRemoteConnector;
                    task.RestUserToWait = ftd.UserWait;
                    task.OnServerStateUpdated();
                } break;

                case FileTransportType.CouldSendFile:
                {
                    var task = FindTask(ftd.TransportID, ftd.SenderID);
                    task.State = FileTransportState.Transport;
                    if (ftd.Connection != null)
                    {
                        task.Connection = ftd.Connection;
                    }
                    task.OnServerStateUpdated();
                } break;
                }
            }
            if (message.MessageType == PrimaryMessageType.FileTransportServerToClient)
            {
                var ftd = message.ClientData.GetSerializeAble <FileTransportData>();
                switch (ftd.Type)
                {
                case FileTransportType.WantSendFile:
                {
                    var task = new FileTransportTask();
                    task.ID           = ftd.TransportID;
                    task.State        = FileTransportState.WaitForLocalConnector;
                    task.TargetUser   = Manager.Users.GetUserFromId(message.MessageRoot.RemoteId);
                    task.Size         = ftd.Size;
                    task.DatasetCount = ftd.Datasets;
                    task.Connection   = ftd.Connection;
                    Tasks.Add(task);
                    if (RemoteTaskAdded != null)
                    {
                        RemoteTaskAdded(task);
                    }
                    Connection con = null;
                    if (Role != ServerClientRole.Client)
                    {
                        con = FindEmptyConnection();
                        userwait++;
                        while (con == null)
                        {
                            var pm = new PrimaryMessage();
                            pm.MessageRoot = message.MessageRoot;
                            pm.MessageType = PrimaryMessageType.FileTransportClientToServer;
                            ftd.UserWait   = task.RestUserToWait = userwait;
                            ftd.Type       = FileTransportType.WaitToGetPort;
                            pm.ClientData.SetSerializeAble(ftd);
                            Manager.SendMessage(pm);
                            System.Threading.Thread.Sleep(10);
                            con = FindEmptyConnection();
                        }
                        SetUsedState(con, true);
                        userwait--;
                        task.Connection = con;
                    }
                    var rm = new PrimaryMessage();
                    rm.MessageRoot = message.MessageRoot;
                    rm.MessageType = PrimaryMessageType.FileTransportClientToServer;
                    ftd.Type       = FileTransportType.CouldSendFile;
                    ftd.Connection = con;
                    rm.ClientData.SetSerializeAble(ftd);
                    Manager.SendMessage(rm);

                    task.State = FileTransportState.Transport;
                    task.OnServerStateUpdated();
                    TcpListener tcplist = null;
                    TcpClient   tcp     = null;

                    if (Role == ServerClientRole.Client)
                    {
                        tcp = new TcpClient(task.Connection.Target, task.Connection.Port);
                    }
                    else
                    {
                        tcplist = new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any, con.Port));
                        tcplist.Start();
                        tcp = tcplist.AcceptTcpClient();
                    }
                    var stream = tcp.GetStream();

                    if (task.DatasetCount == 0)
                    {
                        var l = new List <byte>();
                        var b = new byte[tcp.ReceiveBufferSize];
                        int len;
                        while (true)
                        {
                            len = stream.Read(b, 0, b.Length);
                            l.AddRange(b.ToList().GetRange(0, len).ToArray());
                            task.TransportedBytes += len;
                            task.OnServerStateUpdated();
                            if (len < b.Length)
                            {
                                System.Threading.Thread.Sleep(1);
                                if (stream.DataAvailable || tcp.Available > 0)
                                {
                                    continue;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }

                        tcp.Close();
                        if (tcplist != null)
                        {
                            tcplist.Stop();
                        }
                        task.CompressedBytes = l.ToArray();
                    }
                    else
                    {
                        for (task.CurrentDataset = 0; task.CurrentDataset < task.DatasetCount; ++task.CurrentDataset)
                        {
                            var l = new List <byte>();
                            var b = new byte[tcp.ReceiveBufferSize];
                            stream.Read(b, 0, 4);
                            var length = BitConverter.ToInt32(b, 0);
                            int len;
                            var timeout = false;
                            task.Size             = length;
                            task.TransportedBytes = 0;
                            while (!timeout)
                            {
                                len = stream.Read(b, 0, b.Length);
                                l.AddRange(b.ToList().GetRange(0, len).ToArray());
                                task.TransportedBytes += len;
                                task.OnServerStateUpdated();
                                if (len < b.Length)
                                {
                                    if (l.Count >= length)
                                    {
                                        break;                            //Fertig
                                    }
                                    int i = 0;
                                    if (!tcp.Connected)
                                    {
                                        timeout = true;
                                        break;
                                    }
                                    for (; i < 2000; ++i)
                                    {
                                        System.Threading.Thread.Sleep(1);
                                        if (stream.DataAvailable || tcp.Available > 0)
                                        {
                                            break;
                                        }
                                    }
                                    if (i == 2000)
                                    {
                                        timeout = true;
                                        break;         //Timeout nach 2 Sekunden
                                    }
                                }
                            }
                            if (timeout)
                            {
                                break;
                            }
                            task.OnDatasetReceived(task.CurrentDataset, l.ToArray());
                        }
                        tcp.Close();
                        if (tcplist != null)
                        {
                            tcplist.Stop();
                        }
                    }

                    task.State = FileTransportState.DecompressBytes;
                    task.OnServerStateUpdated();
                    if (CompressBytes && task.DatasetCount == 0)
                    {
                        using (var m = new MemoryStream(task.CompressedBytes))
                            using (var defl = new DeflateStream(m, CompressionMode.Decompress))
                                using (var m2 = new MemoryStream())
                                    using (var r = new BinaryReader(m2))
                                    {
                                        defl.CopyTo(m2);
                                        m2.Position = 0;
                                        task.Data   = r.ReadBytes((int)m2.Length);
                                    }
                    }
                    else
                    {
                        task.Data = task.CompressedBytes;
                    }

                    task.State = FileTransportState.Finished;
                    task.OnServerStateUpdated();
                    if (RemoteTaskFinished != null)
                    {
                        RemoteTaskFinished(task);
                    }
                    Tasks.Remove(task);
                    SetUsedState(con, false);
                }
                break;
                }
            }
        }
예제 #2
0
        public void StartTask(FileTransportTask task) //Sender
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }
            if (task.State != FileTransportState.Waiting)
            {
                throw new ArgumentException();
            }
            Tasks.Add(task);
            var t = new Task(() =>
            {
                #region Daten verkleinern nur ohne Datasets
                if (CompressBytes && task.DatasetCount == 0)
                {
                    task.State = FileTransportState.CompressBytes;
                    using (var m = new MemoryStream())
                        using (var comp = new DeflateStream(m, CompressionMode.Compress))
                            using (var r = new BinaryReader(m))
                                using (var w = new BinaryWriter(comp))
                                {
                                    w.Write(task.Data);
                                    m.Position           = 0;
                                    task.CompressedBytes = r.ReadBytes((int)m.Length);
                                }
                }
                else
                {
                    task.CompressedBytes = task.Data;
                }
                task.Size = task.CompressedBytes.Length;
                #endregion
                //Verbinden
                task.State     = FileTransportState.WaitForLocalConnector;
                Connection con = null;
                if (Role == ServerClientRole.Server)
                {
                    con = FindEmptyConnection();
                    while (con == null)
                    {
                        System.Threading.Thread.Sleep(10);
                        con = FindEmptyConnection();
                    }
                    SetUsedState(con, true);
                    task.Connection = con;
                }
                task.State = FileTransportState.ConnectToServer;
                Action act = null;
                act        = new Action(() =>
                {
                    if (task.State == FileTransportState.Transport && task.TransportedBytes == 0)
                    {
                        TcpClient tcp      = null;
                        TcpListener server = null;
                        if (Role == ServerClientRole.Server)
                        {
                            server = new TcpListener(IPAddress.Any, con.Port);
                            server.Start();
                            tcp = server.AcceptTcpClient();
                            server.Stop();
                            server = null;
                        }
                        else
                        {
                            tcp = new System.Net.Sockets.TcpClient();
                            tcp.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(task.Connection.Target), task.Connection.Port));
                        }

                        var stream = tcp.GetStream();

                        if (task.DatasetCount == 0)
                        {
                            var offset = 0;
                            while (offset < task.CompressedBytes.Length)
                            {
                                stream.Write(task.CompressedBytes, offset, Math.Min(task.CompressedBytes.Length - offset, tcp.SendBufferSize));
                                System.Threading.Thread.Sleep(1);
                                offset += tcp.SendBufferSize;
                                task.TransportedBytes = Math.Min(task.CompressedBytes.Length, offset);
                                task.OnServerStateUpdated();
                            }
                        }
                        else
                        {
                            for (task.CurrentDataset = 0; task.CurrentDataset < task.DatasetCount; ++task.CurrentDataset)
                            {
                                var bytes      = task.OnGetDatasetData(task.CurrentDataset);
                                var datalength = BitConverter.GetBytes(bytes.Length);
                                stream.Write(datalength, 0, datalength.Length);
                                var offset            = 0;
                                task.Size             = bytes.Length;
                                task.TransportedBytes = 0;
                                while (offset < bytes.Length)
                                {
                                    if (!tcp.Connected)
                                    {
                                        break;
                                    }
                                    stream.Write(bytes, offset, Math.Min(bytes.Length - offset, tcp.SendBufferSize));
                                    System.Threading.Thread.Sleep(1);
                                    offset += tcp.SendBufferSize;
                                    task.TransportedBytes = Math.Min(bytes.Length, offset);
                                    task.OnServerStateUpdated();
                                }
                                if (!tcp.Connected)
                                {
                                    break;
                                }
                            }
                        }

                        tcp.Close();
                        task.State = FileTransportState.Finished;
                        Tasks.Remove(task);
                        task.OnServerStateUpdated();
                        task.ServerStateUpdated -= act;
                        if (con != null)
                        {
                            SetUsedState(con, false);
                        }
                    }
                });
                task.ServerStateUpdated += act;
                var mes         = new PrimaryMessage();
                var ftd         = new FileTransportData();
                ftd.TransportID = task.ID;
                ftd.SenderID    = Manager.CurrentId.Id;
                ftd.Type        = FileTransportType.WantSendFile;
                ftd.Size        = task.Size;
                ftd.Datasets    = task.DatasetCount;
                ftd.Connection  = task.Connection;
                mes.ClientData.SetSerializeAble(ftd);
                mes.MessageType            = PrimaryMessageType.FileTransportServerToClient;
                mes.MessageRoot.Connection = task.TargetUser.DefaultConnection;
                mes.MessageRoot.Connector  = task.TargetUser.DefaultConnector;
                mes.MessageRoot.RemoteId   = task.TargetUser.Id;
                Manager.SendMessage(mes);
            });

            t.Start();
        }