реклама на сайте
подробности

 
 
> VS2010 прием по TCP, доступ к главной форме из потока
smk
сообщение Nov 23 2015, 20:35
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'chart1' не из того потока, в котором он был создан.

В приложении, которое мне необходимо для работы нужно принимать пакет данных по ТСП и "распихивать" их по элементам главной формы. Прием ведется в отдельном потоке:
Код
                Thread th = new Thread(ReceiveRun);
                th.Start();


        // Цикл извлечения сообщений,
        // запускается в отдельном потоке.
        void ReceiveRun()
        {
            while (true)
            {
                try
                {
                    string s = null;
                    while (ns.DataAvailable == true)
                    {
                        //// Определение необходимого размера буфера приема.
                        //byte[] buffer = new byte[_tcpСlient.Available];

                        ns.Read(inBuffer, 0, inBuffer.Length);
                        s += Encoding.Default.GetString(inBuffer);
                    }

                    if (s != null)
                    {
                        ShowReceiveMessage(s);
                        s = String.Empty;
                    }


                    // Вынужденная строчка для экономия ресурсов процессора.
                    // Неизящный способ.
                    Thread.Sleep(100);
                }
                catch
                {
                    ErrorSound();
                }

                if (_stopNetwork == true) break;

            }
        }



При попытке получить пакет появляется ошибка, которую я привел в начале этого сообщения. Ошибка появляется при обработке функции отображения данных:

Код
       // Код доступа к свойствам объектов главной формы  из других потоков
        delegate void UpdateReceiveDisplayDelegate(string message);
        void ShowReceiveMessage(string message)
        {
            if (chart1.InvokeRequired == true)
            {
                UpdateReceiveDisplayDelegate rdd = new UpdateReceiveDisplayDelegate(ShowReceiveMessage);

                // Данный метод вызывается в дочернем потоке,
                // ищет основной поток и выполняет делегат указанный в качестве параметра
                // в главном потоке, безопасно обновляя интерфейс формы.
                Invoke(rdd, new object[] { message });
                chart1.Series[0].Points.Clear();
                chart1.Series[1].Points.Clear();
                chart1.Series[2].Points.Clear();
                chart1.Series[3].Points.Clear();
                chart1.Series["1,3 мкм"].Points.AddY(inBuffer[1] << 8 + inBuffer[0]);
                chart1.Series["2,11 мкм"].Points.AddY(inBuffer[3] << 8 + inBuffer[2]);
                chart1.Series["1,8 мкм"].Points.AddY(inBuffer[5] << 8 + inBuffer[4]);
                chart1.Series["1,93 мкм"].Points.AddY(inBuffer[7] << 8 + inBuffer[6]);
            }
            else
            {
                // Если не требуется вызывать метод Invoke, обратимся напрямую к элементу формы.
                chart1.Series[0].Points.Clear();
                chart1.Series[1].Points.Clear();
                chart1.Series[2].Points.Clear();
                chart1.Series[3].Points.Clear();
                chart1.Series["1,3 мкм"].Points.AddY(inBuffer[1] << 8 + inBuffer[0]);
                chart1.Series["2,11 мкм"].Points.AddY(inBuffer[3] << 8 + inBuffer[2]);
                chart1.Series["1,8 мкм"].Points.AddY(inBuffer[5] << 8 + inBuffer[4]);
                chart1.Series["1,93 мкм"].Points.AddY(inBuffer[7] << 8 + inBuffer[6]);
            }


        }


Как правильно поступить с выводом информации? Прошу помочь. Спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 27)
XVR
сообщение Nov 25 2015, 06:37
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



У вас в ShowReceiveMessage жуткая мешанина из того, что нужно вызывать в потоке приема и того, что нужно вызывать в GUI потоке.

В потоке приема нужно вызывать ТОЛЬКО Invoke от делегата (от ShowReceiveMessage), а в самой ShowReceiveMessage уже обновлять всю GUI часть
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 25 2015, 08:34
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Nov 25 2015, 08:37) *
У вас в ShowReceiveMessage жуткая мешанина из того, что нужно вызывать в потоке приема и того, что нужно вызывать в GUI потоке.

В потоке приема нужно вызывать ТОЛЬКО Invoke от делегата (от ShowReceiveMessage), а в самой ShowReceiveMessage уже обновлять всю GUI часть

Спасибо, что откликнулись. Можно попросить уточнить (на пальцах) что куда перенести? Прошу простить, не силен в этой стороне программирования и прибегаю только когда действительно не обойтись. В идеале если есть у Вас какая-то "коза" с правильной организацией вопроса, то был бы очень признателен. А вообще хотелось бы так чтобы в одном потоке происходил прием, а вдругом обработка. Пришло что-то - выставили флаг. В обработчике увидели флаг - обработали что пришло. Как правильно сделать тсп-клиент под это я не знаю. Потому нужна помощь. С остальным, думаю разберусь. Спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 25 2015, 10:15
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Конструкцию UpdateReceiveDisplayDelegate rdd = new UpdateReceiveDisplayDelegate(ShowReceiveMessage); вынести из ShowReceiveMessage и поместить в начало ReceiveRun
Конструкцию Invoke(rdd, new object[] { message }); вынести из ShowReceiveMessage и пометить в ReceiveRun вместо вызова ShowReceiveMessage
Прямые обращения к inBuffer в ShowReceiveMessage заменить на обращения к ее декодированному содержимому, декодировать его из параметра message
В ShowReceiveMessage ветку под if (chart1.InvokeRequired == true) убрать
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 25 2015, 11:29
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Благодарю. Сделаю как Вы сказали. Еще раз спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 25 2015, 14:25
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Nov 25 2015, 12:15) *
Конструкцию Invoke(rdd, new object[] { message }); вынести из ShowReceiveMessage и пометить в ReceiveRun вместо вызова ShowReceiveMessage

Сделал. Пишет, что "Элемент "message" не существует в текущем контексте." Можно с этим что-то сделать? Спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 25 2015, 14:36
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



В контексте ReceiveRun этот элемент называется s. Т.е. надо Invoke(rdd, new object[] { s });
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 28 2015, 09:42
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Пока получается. Остается вопрос по кнопке "отсоединиться". Отсоединиться получается, но потом не соединяется т.к. элемент _tcpСlient ликвидирован. Что можно сделать? И еще. Я тут "козу" набросал. Посмотрите пожалуйста на предмет правильности и нужно как-то сделать так чтоб void Display() выводила в отдельном потоке. По событию таймера выводит. Заранее прошу прощения за навязчивость, но помощи ждать больше неоткуда. Если удастся привести проект в порядок, то будет мне коза на все случаи жизни.
Прикрепленный файл  myTCP.zip ( 71.43 килобайт ) Кол-во скачиваний: 40


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 28 2015, 13:57
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



И еще такой момент. тспклиент принимает ровно 16 посылок. не понимаю что его ограничивает.
Собственно проект, который принмает только 16 посылок. Прикрепленный файл  tcpclient.zip ( 80.66 килобайт ) Кол-во скачиваний: 32

Даже не представляю как так получается. Ничего такого и близко нет. Может кто поможет понять что за чудеса? Спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 30 2015, 11:47
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(smk @ Nov 28 2015, 12:42) *
Пока получается. Остается вопрос по кнопке "отсоединиться". Отсоединиться получается, но потом не соединяется т.к. элемент _tcpСlient ликвидирован. Что можно сделать?
Я не в курсе, можно ли вызвать Connect у TCPClient после Close, но если нельзя, то можно заново создать TCPClient:
Код
        private void button2_Click(object sender, EventArgs e)
        {
            tcpСlient.Close();
            tcpStream.Close();
            tcpСlient = new TcpClient();
        }

Цитата
нужно как-то сделать так чтоб void Display() выводила в отдельном потоке.
Для этого нужен отдельный поток и вызывать оттуда сам Display через делегат
Вызывать экранные элементы из GUI можно ТОЛЬКО из того потока, где они создавались
Цитата
И еще такой момент. тспклиент принимает ровно 16 посылок. не понимаю что его ограничивает.

Может сервер закрывает соединение?
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 30 2015, 19:25
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Nov 30 2015, 13:47) *
Может сервер закрывает соединение?

Точно нет. проверил. Есть такая программка - hercules-3-2-8. С ней работает на ура. Вот бы посмотреть как сделано.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 1 2015, 11:42
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



А что происходит после приема 16 посылок? Останавливается поток или закрывается соединение? Или еще что то?
Цитата
Есть такая программка - hercules-3-2-8. С ней работает на ура.
Может надо что то серверу передавать? Посмотрите WireShark'ом обмен с hercules-3-2-8
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 1 2015, 13:18
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Dec 1 2015, 13:42) *
А что происходит после приема 16 посылок? Останавливается поток или закрывается соединение? Или еще что то?
Может надо что то серверу передавать? Посмотрите WireShark'ом обмен с hercules-3-2-8

После 16 посылок перестают отображаться новые данные, хотя они передаются. Шарком смотрел. Связь организована именно путем запрос-ответ. Геркулес нормально общается, передает запрос и получает ответ сколько угодно раз. Еще раз сегодня все уточню что в сети происходит для порядка...
Сервер это контроллер с кейловским стеком. Он и реньше нормально работал и сейчас повода для претензий не вижу.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Dec 2 2015, 07:54
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Может что то с отображением данных в gui.
Попробуйте вставить лог в это место
Код
  if (s != null)
{
запись в лог s
ShowReceiveMessage(s);
        s = String.Empty;
}
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 2 2015, 14:39
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



В прикрепленном проекте все хорошо кроме приема данных. Соединяется, передает, разъединяется, повторно соединяется. Принимает сколько угодно пакетов. Но при приеме никак не выходит отобразить данные, хотя доподлинно известно, что они есть и валидны. Как только пытаюсь что-то вывести примет первый пакет и все. Счетчик показывает 1 и не меняется. Если часть вывода закоментировать, то выводит нули, хотя знаю что не должно быть нулей. Может как-то неправильно в функцию вывода передается массив, но при этом счетчик выводит правильно. Помогите сделать прием пожалуйста. Я уже не знаю что можно еще предпринять.
Прикрепленный файл  myTCP.zip ( 86.93 килобайт ) Кол-во скачиваний: 46

Как-то трудно на словах описать внятно. Если кто сможет, просто попробуйте.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 2 2015, 15:05
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Чтение у вас сделано мягко говоря необычно sm.gif

Ваш код с комментариями

Код
                            byte[] bytes = new byte[tcpСlient.ReceiveBufferSize];
// Заказываете буфер для чтения неизвестно какого размера -
//  то, что вернет tcpСlient.ReceiveBufferSize тут и то, что он вернет 3мя строками позже не обязательно совпадают

                            while (tcpStream.DataAvailable == true)
// Если данные есть - читаем их, если нет - то не читаем, а выдаем пустой buffer
// (returndata во 2й раз будет не null, а String.Empty)
                            {
                                tcpStream.Read(bytes, 0, (int)tcpСlient.ReceiveBufferSize);
                                returndata = Encoding.UTF8.GetString(bytes);
// Это зачем ???
                                count++;
                            }
                            if (returndata != null)
// Это просто жесть :)
                            {
                                Invoke(rdd, new object[] { bytes });
                                str = returndata;
                                returndata = String.Empty;
                            }

Код жуткий, кроме того, он выдаст нечто нарезанное далеко не по границам пакетов
Пакет нужно собирать в приемной нити, и отдавать целиком в Display
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 2 2015, 18:19
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Спасибо. Что-то я догадываюсь как исправить, но "жесть" даже не понимаю куда двигаться. Приложение нужно уже вчера. Может поможете?

А как сделать так чтоб обычно? Главное надежность. Посылка приходит каждые 30-40 мС.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 2 2015, 20:38
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



returndata и все манипуляции вокруг него не нужны вообще
Вызывать Invoke(rdd,...) нужно сразу после tcpStream.Read и передавать в него разиер реально прочтенных данных, но лучше все же собирать пакет после tcpStream.Read, и только готовый отдавать на показ

Какой формат принимаемых пакетов?

Go to the top of the page
 
+Quote Post
smk
сообщение Dec 3 2015, 07:50
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Dec 2 2015, 22:38) *
returndata и все манипуляции вокруг него не нужны вообще
Вызывать Invoke(rdd,...) нужно сразу после tcpStream.Read и передавать в него разиер реально прочтенных данных, но лучше все же собирать пакет после tcpStream.Read, и только готовый отдавать на показ

Какой формат принимаемых пакетов?

Спасибо. Формат сейчас 256 байт вне зависимости от того сколько реально значащих. К-во значащих зависит от содержания запроса, остальные при формировании буфера передачи просто не модифицируются. В целом размер передаваемого буфера всегда будет не более 256 байт и может меняться только в сторону уменьшения. Оптимольный размер покажет практика. Хочу спросить, что значит "собирать пакет"? Как это делается?

Вот так сейчас сделал. Счетчик тикает, данные идут, отображения всеравно нет.


Код
        private void ReceiveRun()
        {
            
            UpdateReceiveDisplayDelegate rdd = new UpdateReceiveDisplayDelegate(Display);
            try
            {
                while (true)
                {
                        if (tcpStream.CanRead)
                        {
                            byte[] bytes = new byte[256];
                            while (tcpStream.DataAvailable == true)
                            {
                                tcpStream.Read(bytes, 0, (int)256);
                                count++;
                            }
                            Invoke(rdd, new object[] { bytes });
                         }
                        else
                        {
                            label1.Text = "Прием невозможен";
                            th.Abort();
                            tcpСlient.Close();
                            tcpStream.Close();
                            return;
                        }
                 }
            }
            catch
            {
                label1.Text = "ошибка";
            }
        }

        delegate void UpdateReceiveDisplayDelegate(Byte [] mydata);
        private void Display(Byte[] mydata) //вывод на форму
        {
            Int32 temp;
            temp = ((mydata[3] << 24) + (mydata[2] << 16) + (mydata[1] << 8) + mydata[0]);
            label1.Text = temp.ToString("D");
            label3.Text = Convert.ToString(count);
                //if (mydata[0] > 0) label2.Text = "OK";
                //else label2.Text = "0";
        }


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 3 2015, 12:36
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата
Хочу спросить, что значит "собирать пакет"?
Это значит, что TCP соединение не является datagram ориентированным. Т.е. это просто поток байтов. И никто не гарантирует, что приемная сторона будет получать эти байты кусками такого же размера, как передавала передающая сторона. Т.е. вы свои 256 байт можете получить в несколько чтений (и мелкой нарезкой).

Цитата
Как это делается?
Принимаются данные и накапливаются в буфере, пока не наберется полный пакет.

Цитата
while (tcpStream.DataAvailable == true)
{
tcpStream.Read(bytes, 0, (int)256);
count++;
}
Invoke(rdd, new object[] { bytes });
Это неправильно. У вас в буфере будет мешанина из кусков принятых данных. Надо как то так
Код
byte[] bytes = new byte[256];
...

int size = 0;
while(size<256)
{
  while (tcpStream.DataAvailable == true)
   {
     size+=tcpStream.Read(bytes, size, 256-size);
   }
  if (size<256) Thread::Sleep(100);
}
count++;

Invoke(rdd, new object[] { bytes });

Go to the top of the page
 
+Quote Post
smk
сообщение Dec 3 2015, 14:03
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Судя по режиму отладки функция Display выполняется очень часто. И действительно в буфере нули. Если и приходит что-то, то оно сразуже затирается нулями при следующем вызове Display. Как красиво сделать так чтоб Display вызывалась только если приняты свежие данные?
Пока сделал вот так:
Код
if(count_old != count)Invoke(rdd, new object[] { bytes });

Но всеравно в Display передаются нули.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 3 2015, 14:15
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Нужно правильно принимать. См сообщение №20
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 3 2015, 14:31
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Кажись заработало. пока-что... Тестирую. Спасибо! Поглядывайте пока в тему пожалуйста... пока тестирую.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 3 2015, 20:45
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Вот что получается. Если я кнопкой отправляю 16 запросов то после 16-го все последующие не обрабатываются. Ну или еще один с большой задержкой. Если я командую прибору отвечать без запроса - молотит без сбоев. Если геркулесом отправляю запросы - тоже никаких проблем, отвечает хоть на 50-й. Даже не представляю каким способом вычислить этот затык. Можно что-то придумать? Спасибо.

Содержание пакета не имеет значения. Просто перестает отправлять или вообще подвисает. На мой непрофессиональный взгляд все вполне должно работать.
Код
       private void button3_Click(object sender, EventArgs e)//Отправить
        {

            if (tcpStream.CanWrite)
            {
                outBuffer[0] = 1;
                if (checkBox1.Checked)
                {
                    outBuffer[1] = 2;
                    outBuffer[2] = 1;
                }
                else
                {
                    outBuffer[1] = 2;
                    outBuffer[2] = 0;
                }
  
                tcpStream.Write(outBuffer, 0, outBuffer.Length);
            }
            else
            {
                label1.Text = "Передача невозможна";
                th.Abort();
                tcpСlient.Close();
                tcpStream.Close();
                return;
            }
        }


Как я успел понять - программа ничего не отсылает. Почему - непонятно.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 4 2015, 08:13
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



похоже, что проблема со стороны прибора. проверю - напишу.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 4 2015, 10:15
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



А чему равен outBuffer.Length ?
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 4 2015, 13:03
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(XVR @ Dec 4 2015, 12:15) *
А чему равен outBuffer.Length ?

всегда 256. проверял. Насколько я успел понять, то с приемной стороны забивается окно приема. Выправил, но не проверил еще.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 4 2015, 23:05
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Все отлично работает. Прием и передача ОК. Огромное спасибо!


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 01:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01671 секунд с 7
ELECTRONIX ©2004-2016