Exemple #1
0
        // методы работы с исходящим подключением
        /// <summary>
        /// Запускает процесс поиска маршрута
        /// </summary>
        /// <param name="target">Целевой компьютер</param>
        /// <param name="mat">Ид раздачи</param>
        /// <returns>Сокет, подключенный к следующему компьютеру в цепочке, либо null, если маршрут не удалось установить</returns>
        public Socket Connect(Client target, int mat)
        {
            foreach (Material m in ProgramMaterials.MaterialsArray)
            {
                foreach (Connection c in m.Connections)
                {
                    try
                    {
                    IPAddress ip = ((IPEndPoint)c.Socket.RemoteEndPoint).Address;
                    short port = 30095;
                    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                    try { sock.Connect(ip, port); }
                    catch (Exception) { continue; }
                    NetworkStream comStr = new NetworkStream(sock);
                    comStr.WriteByte((byte)IDT_Protocol.Connect);
                    int resp = comStr.ReadByte();

                    if(resp != (int)IDT_Protocol.Connected)
                    { TerminateConnection(comStr); continue; }

                    byte[] temp = target.Serialize();
                    comStr.WriteByte((byte)IDT_Protocol.IsLink);
                    comStr.Write(temp, 0, 6);
                    resp = comStr.ReadByte();

                    if(resp != (int)IDT_Protocol.LinkAccesible)
                    { TerminateConnection(comStr); continue; }

                    comStr.WriteByte((byte)IDT_Protocol.IsMaterial);
                    comStr.Write(bc.GetBytes(mat), 0, 4);
                    IDT_Protocol res = (IDT_Protocol)comStr.ReadByte();
                    if(res == IDT_Protocol.MaterialNotFound)
                        comStr.WriteByte((byte)IDT_Protocol.TerminateTransaction);

                    return sock;
                    }
                    catch (Exception)
                    {

                        continue;
                    }
                }
            }
            return null;
        }
Exemple #2
0
        /// <summary>
        /// Пытается произвести рекурсивное подключение от компьютера к компьютеру, пока не установит цепочку связей до конечного компьютера
        /// </summary>
        /// <param name="con">Предыдущий компьютер в сети</param>
        /// <param name="targetHost">Целевой компьютер</param>
        /// <param name="mat">Ид раздачи</param>
        /// <returns>Сокет, подключенный к следующему компьютеру в цепочке, либо null, если маршрут не удалось установить</returns>
        Socket TryConnect(Connection con, out Client targetHost, int mat)
        {
            NetworkStream nStream = new NetworkStream(con.Socket);
            byte[] buf = new byte[6];
            nStream.Read(buf, 0, 6);
            targetHost = new Client();
            targetHost.Deserialize(buf);

            foreach (Client c in targets)
            {
                if (c == targetHost)
                {
                    nStream.WriteByte((byte)(IDT_Protocol.TerminateTransaction));
                    return null;
                }
            }
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

            try
            {
                sock.Connect(targetHost.ip, targetHost.port);
                sock.Send(new byte[] { (byte)C_C_Protocol.Connect});
                byte[] receive = new byte[2];
                sock.Receive(receive, 0, 1, SocketFlags.None);
                sock.Receive(receive, 1, 1, SocketFlags.None);
                if((C_C_Protocol) receive[0] != C_C_Protocol.Connected || receive[1] ==0)
                    { sock.Close(); throw new SocketException(); }

                sock.Send(new byte[] {(byte)C_C_Protocol.IsMaterial});
                byte[] temp = bc.GetBytes(mat);
                sock.Send(temp);
                sock.Receive(temp, 1, SocketFlags.None);
                if (temp[0] != (byte)C_C_Protocol.MaterialResponse)
                { sock.Close(); throw new SocketException(); }

                return sock;
            }
            catch (SocketException)
            {
                foreach (Material m in ProgramMaterials.MaterialsArray)
                {
                    foreach (Connection c in m.Connections)
                    {
                        IPAddress ip = ((IPEndPoint)c.Socket.RemoteEndPoint).Address;
                        short port = (short)((IPEndPoint)c.Socket.RemoteEndPoint).Port;
                        try { sock.Connect(ip, port); }
                        catch (Exception) { continue; }
                        return Connect(targetHost, mat);

                    }
                }
                return null;
            }
        }
Exemple #3
0
        /// <summary>
        /// Процедура, содержащая цикл обработки команд протокола IDT
        /// </summary>
        /// <param name="con">Объект подключения с инициатором сеанса</param>
        private void IDTSession(object con)
        {
            Connection c = (Connection)con;

            NetworkStream nStream = new NetworkStream(c.Socket);

            /*общие данные*/
            Socket sock = null;
            int material = 0;
            Client targetHost = new Client() ;

            IDT_Protocol com = (IDT_Protocol)nStream.ReadByte();
            nStream.Close();

            switch (com)
            {
                case IDT_Protocol.IsLink:
                    targets.Add(targetHost);
                    sock = TryConnect(c, out targetHost, material);
                    break;
                case IDT_Protocol.IsMaterial:
                    material = CheckMaterial(c,sock, targetHost);
                    break;
                case IDT_Protocol.GetPart:
                    RequestPart(c, sock, material, targetHost);
                    break;
                case IDT_Protocol.TerminateTransaction:
                    targets.Remove(targetHost);
                    break;

            }
        }
Exemple #4
0
        /// <summary>
        /// Метод запрашивает часть данных у подключенного IDT сервиса, либо конечного компьютера и отправляет ее инициатору подключения - 
        /// другому IDT сервису, либо первому компьютеру в цепочке
        /// </summary>
        /// <param name="c">Объект подключения с инициатором</param>
        /// <param name="sock">Сокет, подключенный к следующему компьютеру в цепочке</param>
        /// <param name="material">Идентификатор раздачи</param>
        /// <param name="targetHost">Целевой компьютер, для достижения которого строилась цепочка</param>
        private void RequestPart(Connection c, Socket sock, int material, Client targetHost)
        {
            NetworkStream nStream = new NetworkStream(sock);
            NetworkStream ansStream = new NetworkStream(c.Socket);

            byte[] bcom = new byte[] { (byte)C_C_Protocol.GetPart };
            byte[] bmat = bc.GetBytes(material);
            byte[] bfile = new byte[4];
            byte[] bpart = new byte[4];

            byte[] bsize = new byte[4];

            ansStream.Read(bfile, 0, 4);
            ansStream.Read(bpart, 0, 4);
            ansStream.Read(bsize, 0, 4);

            int size = bc.ToInt32(bsize, 0);

            // Работа в режиме целевого компьютера
            if (IsTarget(sock, targetHost))
            {

                nStream.Write(bcom, 0, 1);
                nStream.Write(bmat, 0, 1);
                nStream.Write(bfile, 0, 4);
                nStream.Write(bpart, 0, 4);

                C_C_Protocol resp = (C_C_Protocol)nStream.ReadByte();
                int ispart = nStream.ReadByte();
                if (resp != C_C_Protocol.SendPart || ispart == 0)
                {
                    ansStream.WriteByte((byte)IDT_Protocol.SendPart);
                    ansStream.WriteByte(0);
                    return;
                }
                nStream.Read(new byte[12], 0, 12);

                byte[] buffer = new byte[size];
                for (int i = 0; i != size; )
                {
                    i += nStream.Read(buffer, i, size - i);
                }
                ansStream.WriteByte((byte)IDT_Protocol.SendPart);
                ansStream.WriteByte(0);
                ansStream.Write(buffer, 0, size);
            }
            else//работа в режиме промежуточной ячейки сети
            {
                IDT_Protocol resp = (IDT_Protocol) nStream.ReadByte();
                int status = nStream.ReadByte();
                if (resp != IDT_Protocol.SendPart) return;
                if (status == 0)
                {
                    ansStream.WriteByte((byte)IDT_Protocol.SendPart);
                    ansStream.WriteByte((byte)status);
                    return;
                }
                byte[] buffer = new byte[size];
                for (int i = 0; i != size; )
                {
                    i += nStream.Read(buffer, i, size - i);
                }

                ansStream.WriteByte((byte)IDT_Protocol.SendPart);
                ansStream.WriteByte((byte)status);
                ansStream.Write(buffer, 0, size);
            }
        }
Exemple #5
0
        /// <summary>
        /// Проверяет наличие раздачи на конечном компютере, команда передается по цепочке
        /// </summary>
        /// <param name="c">Объект подключения с инициатором</param>
        /// <param name="sock">Сокет, подключенный к следующему компьютеру в цепочке</param>
        /// <param name="targetHost">Целевой компьютер, для достижения которого строилась цепочка</param>
        /// <returns>Возвращает номер раздачи, полученный от предыдущего компьютера в цепи</returns>
        private int CheckMaterial(Connection con, Socket sock, Client targetHost)
        {
            NetworkStream nStream = new NetworkStream(sock);
            NetworkStream ansStream = new NetworkStream(con.Socket);
            byte[] temp = new byte[4];
            ansStream.Read(temp, 0, 4);
            int material = bc.ToInt32(temp,0);

            if (IsTarget(sock, targetHost)) // работа в режиме целевого хоста
            {
                nStream.Write(new byte[] {(byte)C_C_Protocol.IsMaterial},0,1);
                nStream.Write(temp, 0, 4);
                byte[] resp = new byte[6];
                nStream.Read(resp,0,6);
                if (resp[5] == 1)
                {
                    ansStream.Write(new byte[] { (byte)IDT_Protocol.MaterialConfirmed }, 0, 1);
                    return material;
                }
                else
                {
                    ansStream.Write(new byte[] { (byte)IDT_Protocol.MaterialNotFound }, 0, 1);
                    return 0;
                }
            }
            else // работа в режиме ячейки
            {
                nStream.Write(new byte[] { (byte)C_C_Protocol.IsMaterial }, 0, 1);
                IDT_Protocol resp = (IDT_Protocol)nStream.ReadByte();
                if (resp == IDT_Protocol.MaterialNotFound)
                    return 0;
                else return material;
            }
        }
Exemple #6
0
 /// <summary>
 /// Сравнивает IP и порт следующего компьютера в цепочке.
 /// </summary>
 /// <param name="sock">Сокет следующего компьютера в сети</param>
 /// <param name="targetHost">Целевой компьютер</param>
 /// <returns>True, если следующий компьютер в цепи - конечный</returns>
 private static bool IsTarget(Socket sock, Client targetHost)
 {
     IPAddress ip = ((IPEndPoint)sock.RemoteEndPoint).Address;
     if (targetHost.ip == ip)
         return true;
     return false;
 }
Exemple #7
0
        /// <summary>
        /// Конструктор, вызывается при добавлении раздачи из существующего метафайла
        /// </summary>
        /// <param name="PathToMetaFile">Путь к метафайлу</param>
        public Material(string dir, string PathToMetaFile)
        {
            ProgramMaterials.cur_file = 0;
            BinaryFormatter bf = new BinaryFormatter();
            if (!System.IO.File.Exists(PathToMetaFile))
                throw new Exceptions.IsNotMetafile();

            FileStream metafile = new FileStream(PathToMetaFile, FileMode.Open);
            if (dir[dir.Length - 1] != '\\') dir += "\\";
            try
            {
                Meta_File mf = (Meta_File)bf.Deserialize(metafile);
                IdClient = mf.ID_Client;
                IdMaterial = mf.ID_matirial;
                Name = mf.name;
                server = mf.IP_Port_Server;
                Files = new File[mf.files.Length];

                for (int i = 0; i < mf.files.Length; i++)
                {
                    ProgramMaterials.cur_file = i;
                    Files[i] = new File(mf.files[i].path, dir + mf.files[i].path, mf.files[i].File_Size, mf.files[i].Count_Parts_, mf.files[i].Hashs, mf.files[i].Part_size);
                }
                filese_that_need_to_download = new int[Files.Length];

                cread_map_download();
            }
            catch (System.Runtime.Serialization.SerializationException)
            {
                throw new Exceptions.WrongMetafileFormat();
            }
            finally
            {
                metafile.Close();
            }
            SetSize();
            SetStatus();
        }
Exemple #8
0
        private void ReadClients(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open);
            Read:
            while (fs.Length > fs.Position)
            {
                byte[] temp = new byte[6];
                fs.Read(temp, 0, 6);
                Client t = new Client();
                t.Deserialize(temp);

                IPAddress IP_Client = t.ip;
                short Port_Client = t.port;
                IPEndPoint ip;
                for (int i = 0; i < connections.Count; i++)
                {
                    ip = (IPEndPoint)(connections[i].Socket.RemoteEndPoint);
                    if (ip.Address.ToString() == IP_Client.ToString())
                        goto Read;
                }

                Socket socket_download = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                try
                {
                    Connection con = new Connection();
                    con.Thread = new Thread(Download);
                    con.Thread.IsBackground = true;
                    con.Socket = socket_download;
                    con.Thread.Start(con);
                    socket_download.Connect(new IPEndPoint(IP_Client, Port_Client));
                }
                catch (SocketException)
                {
                    /*if (Config.IDT_Enaibled)
                    {
                        Client cl = new Client(IP_Client, Port_Client);
                        System.Threading.Thread th = new Thread(IDT_client);
                        th.Start(cl);
                    }*/

                }

            }
            fs.Close();
        }
Exemple #9
0
        /// <summary>
        /// Выдает таблицу клиентов
        /// </summary>
        /// <param name="nStream">Открытый сетевой поток</param>
        private void GetClientsTable(NetworkStream nStream)
        {
            byte[] temp = new byte[4];
            nStream.Read(temp, 0, 4);
            int IdMaterial = bc.ToInt32(temp, 0);

            nStream.WriteByte((byte)CTE_Protocol.ReceiveClientsTable);

            foreach (Material m in ProgramMaterials.MaterialsArray)
            {
                if (m.IdMaterial == IdMaterial)
                {

                    int number = m.Connections.Count;

                    temp = bc.GetBytes(number);

                    for (int i = 0; i < number; i++)
                    {
                        IPEndPoint ip = (IPEndPoint) m.Connections[i].Socket.RemoteEndPoint;
                        Client cl = new Client(ip.Address, (short)ip.Port);
                        temp = cl.Serialize();
                        nStream.Write(temp, 0, 6);
                    }
                }
            }
        }