Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
36 / 36 / 6
Регистрация: 06.01.2013
Сообщений: 195
1

Реализация алгоритма цикла

24.01.2013, 15:17. Просмотров 1029. Ответов 9
Метки нет (Все метки)


Приветствую!
В общем сразу к делу!

Метод подключения клиента TCPClient к серверу.

Условие do .... while почему то не правильно работает или я его организовал не правильно, суть такая я вызываю метод, и он ждет когда появится сервер в сети тогда подключается к нему все остальное время выводит сообщение мол сервер не доступен ожидаем, но вместо этого он выдает 2 раза и все, но когда сервер появляется он бесконечное число раз начинает писать дынные не приняты то есть выполняет вот эту процедуру
C#
1
client.ReciveData += new ClienReciveData(resiveData);
Понять не могу как отработать логику что бы такого не было?


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Connecting() //Создание соединения
        {
            string nameClient = textNameClient.Text;
            string ipServer = textIP.Text;
            string port = textPort.Text;
            try
            {
                client = new NetClient(nameClient);//Передаем серверу свое имя
                addItem(client.Status);
                do
                {
                    client.Connect(IPAddress.Parse(ipServer), int.Parse(port)); //Устанавливаем соединение с сервером
                    addItem(client.status);
                    Thread.Sleep(25);
                }
                while (client.isConnect); //Если соединение установлено
 
                client.ReciveData += new ClienReciveData(resiveData);
                textNameServer.Text = client.ServerName;
            }
            catch (SocketException errors)
            {
                string item = String.Format("Ошибка {1}| : {2}", errors.ErrorCode, errors.Message);
                addItem(item);
            }
        }

Тут проект полностью + сервер
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.01.2013, 15:17
Ответы с готовыми решениями:

Реализация алгоритма DES
Помогите исправить ошибку моей реализации DES :(

Реализация алгоритма M-последовательности
Требуется реализовать M-последовательность, количество чисел задаётся пользователем. Реализуется...

Реализация математического алгоритма в программу
Здравствуйте уважаемые. Прошу вашей помощи. Пытаюсь Реализовать алгоритм, но не получается, не могу...

Полная реализация алгоритма MD5 с string
Ребят, помогите найти полную реализацию алгоритма MD5, а не встроенную функцию. Ее та сделать проще...

9
604 / 579 / 157
Регистрация: 29.06.2010
Сообщений: 1,610
24.01.2013, 15:32 2
А ты уверен что именно так и надо: пока есть соединение соединятся? по моему 1 раза вполне хватит, хотя... честно скажу: точно не знаю.

второе: я бы посоветовал обработчик на получение данных выставлять ДО этого странного цикла, который черт на сколько времени может затянуться.

третье: проект у меня не открылся, бо твоя студия новее, но екзеха запускается, обмена данными между клиентом и сервером идёт вроде нормельно. даже между 1 сервером и 2 клиентами
0
36 / 36 / 6
Регистрация: 06.01.2013
Сообщений: 195
24.01.2013, 15:47  [ТС] 3
Смотри обмениваться данными мы можем только после соединения с сервером иначе ошибка.

Ты скорее всего запустил NetServer как клиент и как сервер? если да то это не то=) мой клиент в папке Debug.

Суть приложения такая это будущее ПО для удалённого администрирования =), то есть он должен всегда обмениваться данные с сервером, а если связь с нетом или сервером оборвалась делать перекподключение.

Пытался как то перестроить всю логику приложения и создать метод переподключения ну что то не как не получилось отобрать и сформулировать логику.
0
604 / 579 / 157
Регистрация: 29.06.2010
Сообщений: 1,610
24.01.2013, 17:00 4
начну с малого, постепенно буду добавлять новые лузлы:

C#
1
2
3
4
5
6
7
8
9
10
11
        public bool Connect(IPAddress ip, int port) /// Соединение с сервером.
        {
            if (isConnect == true) return false;
 
            try
            {
                client.Connect(ip, port);
                status = "Устанавливаем соединение...";
                if (isConnect)
                {
...
Добавлено через 51 секунду
при этом isConnect это не поле, возвращающее isConnected объекта client

Добавлено через 12 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public NetClient(string clientName)         /// Создать клиент.
        {
            this.name = clientName;
            client = new TcpClient();
            status = "Создаём клиента ...";
            ThreadReciveData = new Thread(new ThreadStart(_ThreadReciveData));
        }
......
void _ThreadReciveData() /// Поток проверки полученых данных.
        {
            while (true)
            {
                if (client.Available == 0)
                {
                    oldReciveDataSize = 0;
                    status = "Данных от клиента нет ...";               
                }
 
                if (client.Available > oldReciveDataSize)
                {
                    oldReciveDataSize = client.Available;
                    if (ReciveData != null) ReciveData.Invoke(this);
                }
 
                Thread.Sleep(TimeOutUpdate);
            }
        }
при том что запуск потока находится в недостижимом коде, делаю вывод что ThreadStart сразу начинает работу потока. Подключится не может из-за той же самой недостижимости, следовательно и принимать нечего, вот и вышеупомянутые тобой ошибки.

Добавлено через 1 минуту
так что рой метод NetClient.Connect(), всё дело в нём. у тебя, если обратишь внимание, флаг isConnect вообще никогда true не будет.
0
36 / 36 / 6
Регистрация: 06.01.2013
Сообщений: 195
25.01.2013, 03:04  [ТС] 5
Ты имел в виду строку
C#
1
if (isConnect == true) return false;
что никогда не будет true?

Ранее процедура выглядела так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public bool Connect(IPAddress ip, int port) /// Соединение с сервером.
        {
            if (isConnect == true) return false;
 
            try
            {
                //client.Connect(ip, port);
                status = "Устанавливаем соединение...";
                writer = new BinaryWriter(client.GetStream());
                reader = new BinaryReader(client.GetStream());
                writer.Write(name);
                Thread.Sleep(50);
                serverName = reader.ReadString();
                ThreadReciveData.Start();
                isConnect = true;
                status = "Соединение установлено ...";
                return true;
            }
            catch 
            {
                isConnect = false;
                return false;                
            }

Цитата Сообщение от Spectral-Owl Посмотреть сообщение
запуск потока находится в недостижимом коде
объясни почему код недостижим? Ранее этот код работал как часики в архиве приложение NETServer там и клиент и сервер.
0
604 / 579 / 157
Регистрация: 29.06.2010
Сообщений: 1,610
25.01.2013, 10:04 6
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 public bool Connect(IPAddress ip, int port) /// Соединение с сервером.
{
            if (isConnect == true) //если подключено...
                     return false;     //то выход, возвращая лож.
 
//т.е. в эту область мы заходим только если уже не подключено.
            try
            {
                client.Connect(ip, port);//что-то там соединяем...
                status = "Устанавливаем соединение...";//что-то там устанавливаем...
               
//===============бесполезные строки...===========================================//
                
                //вот эта строчка меня немного даже веселит.
                if (isConnect) //если программа сдесь, то isConnect НЕ РАВНО true
                {
                    writer = new BinaryWriter(client.GetStream());
                    reader = new BinaryReader(client.GetStream());
                    writer.Write(name);
                    Thread.Sleep(50);
                    serverName = reader.ReadString();
                    ThreadReciveData.Start();
                    isConnect = true;
                    status = "Соединение установлено ...";
                    return true;
                }
//==========================================================================//
 
 
            //полезные строки
                else
                {
                    //то что мне писало при любой попытки соединения
                    status = "Соединение не установлено, повторная попытка через 2 секунды";
                    return false;
                }
                
            }
            catch //тут я бы посоветовал обработать так, чтобы оповещалось об ошибке.
            {
                isConnect = false;
                return false;                
            }
}
Добавлено через 21 минуту
Цитата Сообщение от Spectral-Owl Посмотреть сообщение
C#
1
if (isConnect) //если программа сдесь, то isConnect НЕ РАВНО true
не совсем корректно выразился, поясню:
если метод дошел до условия, значит он не прекратил свою работу при аналогичном условии выше.
т.е. нечто похожее:
C#
1
2
3
if  (a) {return false;}
if  (a) {a=true;  return true;}
if (!a) {return false;}
0
36 / 36 / 6
Регистрация: 06.01.2013
Сообщений: 195
25.01.2013, 10:16  [ТС] 7
Ты малость не понял =)

Это метод который возвращает если клиент подключен значение False, мол не нужно подключаться, но если он не подключен то идет выполнение кода

C#
1
2
3
4
5
6
7
8
9
 writer = new BinaryWriter(client.GetStream());
                    reader = new BinaryReader(client.GetStream());
                    writer.Write(name);
                    Thread.Sleep(50);
                    serverName = reader.ReadString();
                    ThreadReciveData.Start();
                    isConnect = true;
                    status = "Соединение установлено ...";
                    return true;
Условие
C#
1
2
3
4
5
6
7
8
9
 
                if (isConnect) 
                {
                   ...............
                else
                {
                    status = "Соединение не установлено, повторная попытка через 2 секунды";
                    return false;
                }
Я просто забыл удалить перед тем как выложил, и вопрос был в правильной реализации алгоритма

вот что у меня получилось
NETClient
Form1
0
604 / 579 / 157
Регистрация: 29.06.2010
Сообщений: 1,610
25.01.2013, 14:59 8
очень смущает, теперь, метод:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public void Connecting() //Создание содинения
        {
            do
            {
                Connected(textNameClient.Text, textIP.Text, textPort.Text);
                Thread.Sleep(int.Parse(textTimeReconnection.Text)*1000);
                if (Connected(textNameClient.Text, textIP.Text, textPort.Text) == true) 
                {
                    break;
                }
            }
            while (Connected(textNameClient.Text, textIP.Text, textPort.Text) == true);
        }
он 3 раза пробует выполнять метод Connect, при этом, на мой взгляд, цикл там совершенно ни к чему.
в условии if он выйден из цикла если метод вернёт 1, в условии while он выйдет из цикла если метод вернёт 0.

вообще грамотнее этот метод, на мой взгляд, было сделать какнибудь так:
C#
1
2
3
4
5
6
bool isCon=false;
while (!isCon)
{
isCon=Connect(...);
Thread.Sleep(50);
}
а так, опыта работа с сетевыми программами у меня мало, но вопросы возникают ещё по поводу этого:
C#
1
2
3
4
5
6
7
...
client.ReciveData += new ClienReciveData(resiveData);
...
void resiveData(NetClient c)
{
     addItem("Получены данные: " + client.Reader.ReadString());
}
тут надо знать когда возникает событие генерирующее что сокет с данными, и надо знать что будет прочитано этим странными методом.

При организации чтения данных с ком-порта мне было настолько влом заморачиваться по этому поводу, что события порта не обрабатывал никакие, ограничившись тем что создал поток для чтения и пихал в буффер всё что приходило на порт.
1
36 / 36 / 6
Регистрация: 06.01.2013
Сообщений: 195
25.01.2013, 15:18  [ТС] 9
Спасибо большое за помощь, но это не решает проблемы=)

Тут как бы 2 задачи ожидать появления сервака, и при появлении подключаться, а при разрыве пере подключаться.

Согласно этому
C#
1
2
3
4
5
6
bool isCon=false;
while (!isCon)
{
isCon=Connect(...);
Thread.Sleep(50);
}
Клиент один раз пробует подключится и все, после того как сервак появляется то никаких действий от клиента не производятся =((


метод
C#
1
2
3
4
5
6
client.ReciveData += new ClienReciveData(resiveData);
...
void resiveData(NetClient c)
{
     addItem("Получены данные: " + client.Reader.ReadString());
}
Вызывает чтение всех данных с сокета и выводит их в listBox.
0
604 / 579 / 157
Регистрация: 29.06.2010
Сообщений: 1,610
25.01.2013, 18:03 10
Если ты не переписал метод NetClient.ConnectToServer() то проблемма в нём. хоть ты и сказал что всего-лишь забыл удалить раньше и перевыложил, но в новом файле та-же проблема: стоит первое странное условие.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public bool ConnectToServer(IPAddress ip, int port) /// Соединение с сервером.
{
            if (isConnect == true) return false; //вот оно.
 
            try
            {
                client.Connect(ip, port);
                status = "Устанавливаем соединение...";
                writer = new BinaryWriter(client.GetStream());
                reader = new BinaryReader(client.GetStream());
                writer.Write(name);
                Thread.Sleep(50);
                serverName = reader.ReadString();
                ThreadReciveData.Start();
                isConnect = true;
                status = "Соединение установлено ...";
                return true;
            }
            catch
            {
                isConnect = false;
                return false;
            }
}
Второе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        void _ThreadReciveData() 
        {
            while (true)
            {
                if (client.Available == 0)
                {
                    oldReciveDataSize = 0;
                    status = "Данных от клиента нет ...";
                }
 
                if (client.Available > oldReciveDataSize)
                {
                    oldReciveDataSize = client.Available;
                    if (ReciveData != null) ReciveData.Invoke(this);
                }
                Thread.Sleep(TimeOutUpdate);
            }
        }
...
void resiveData(NetClient c)
        {
            addItem("Получены данные: " + client.Reader.ReadString());//почему не C.Reader.ReadString()?
//хотя в плане одного объекта должно быть всё равно норм.
        }
не уверен что поможет, но как вариант реализовать чтение данных внутри класса клиента, а в событие передовать лишь строку. всёравно у тебя в обработчике уже реализованны доступы к объектам других потоков.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void _ThreadReciveData() 
        {
            while (true)
            {
                if (client.Available == 0)
                {
                    oldReciveDataSize = 0;
                    status = "Данных от клиента нет ...";
                }
 
                if (client.Available > oldReciveDataSize)
                {
                    oldReciveDataSize = client.Available;
                    string recString=this.reader.ReadString();
                    if (ReciveData != null) ReciveData(this, recString);
                }
                Thread.Sleep(TimeOutUpdate);
            }
        }
...
void resiveData(object sender, string recString)
        {
            addItem("Получены данные: "+recString);
        }
ну и следовательно делегат для ReciveData будет иметь вид
C#
1
 public delegate void ClienReciveData(object sender,string recivedString);
третье:
C#
1
2
3
4
5
6
7
8
9
10
11
if (client.Available == 0)
                {
                    oldReciveDataSize = 0;
                    status = "Данных от клиента нет ...";
                }
 
                if (client.Available > oldReciveDataSize)
                {
                    oldReciveDataSize = client.Available;
                    if (ReciveData != null) ReciveData.Invoke(this);
                }
не уверен что нужна проверка такого типа. я так понимаю Available - это сколько готов принять клиент в текущий момент, а oldReciveDataSize - это то сколько он принял в прошлый раз.
Смотря на условие делаю вывод что каждая новая посылка должна быть больше предыдущей. Или не ок вывод, или не ок способ.

А вообще, есть 1 хороший способ организовать поток чтения. некоторые компоненты позволяют выполнять 1 свой метод непозволительно долгое время (банально сколько в тайм-ауте).
к примеру у TcpClient есть свойство Client, а у него есть метод bool Recive(byte[] Buffer), который может выполняться время тайм-аута.

в общем обрати внимание на вот эти строки
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>
        /// Метод на основной поток чтения
        /// </summary>
        private void Read()
        {
            //пока флаг установлен...
            while (WantRead)
            {
                int i = 0;
                //чтение данных с сервера
                try { i = Sock.Receive(bBuffer); }
                //если любая ошибка - остановка
                catch (SocketException e) { Stop(e); return; }
 
                //если принятых байт больше нуля...
                if (i > 0)
                {
                        //получение строки
                        string messaga = Encoding.UTF8.GetString(bBuffer);
 
                        try
                        {
                            //нахождение индекса окончания строки
                            int stopInd = messaga.IndexOf("\0");
                            //выделение сообщения
                            messaga = messaga.Substring(0, stopInd);
                        }
                        catch { }
//вызов соответствющего события
                            if (OnReviceString != null)
                                OnReviceString(this, messaga);
                        }
 
                        //обнуление буффера
                        bBuffer = new byte[1024];
                }
                else
                {
                    //если принятых байт каким-то багом оказалось меньше нуля..
                    //значит сервер обтух и можно отключатся
                    Stop(new Exception("Server shutdown"));
                }
            }
        }
я пару дней не появлюсь
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.01.2013, 18:03

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Реализация алгоритма блочного кода с постоянным смещением
Всем ночь добрая !) Помогите пожалуйста, от чего можно оттолкнуться в следующем задании? ...

Реализация алгоритма кластеризации K-means для монохромных изображений
Доброго времени суток форумчане. Пишу алгоритм кластеризации K-means для монохромных...

Реализация алгоритма передискретизации изображений
Всем доброе время суток. :) Есть задача - реализовать алгоритм изменения размеров изображений с...

Параллельная реализация алгоритма Дейкстры
Объясните пожалуйста каким образом распарллелить можно алг.Дейкстры


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.