Сервер зависает на строке stream.read

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

TrueTrue
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 167
Зарегистрирован: 20.05.2009 (Ср) 23:18

Сервер зависает на строке stream.read

Сообщение TrueTrue » 27.11.2013 (Ср) 0:42

Есть сервер на VB.NET, весь код думаю выкладывать нет смысла, к нему подключается клиент на Android.
Код: Выделить всё
       Private Sub doListen()
            Dim bytes(20480) As Byte
            Dim data As String
            Dim i As Int32 = -1
                While (i <> 0)
                    i = stream.Read(bytes, 0, bytes.Length)
                    data = System.Text.Encoding.UTF8.GetString(bytes, 0, i)
                    RaiseEvent OnRead(Me, data)
                End While

                closeClient()
                RaiseEvent Disconnect(Me, "Клиент №" & Me.Number & " (" & Me.IP & ")" & " отключился от сервера.")
            Catch ex As IO.IOException
                closeClient()
                RaiseEvent Disconnect(Me, "Проблема соединения: " & ex.Message)
            End Try

        End Sub


Принцип работы следующий
Идёт пакет авторизации, после сервер даёт ответ клиенту либо True либо False, что значит Пароль верный или нет.
Сразу после этого, клиент даёт запрос на данные. И сервер уже передаёт нужные данные из базы.

Так вот прикол такой, периодически, закономерность мне выявить не удалось, когда Android работает через Edge интернет, общение клиент сервера прерывается на строке i = stream.Read(bytes, 0, bytes.Length) Тоесть, как буд-то данные клиент не посылает. Хотя я точно знаю, что данные уходят! Но на андроиде висит строка Запрос данных. Значит Андроид запрос отправил.
Когда я тут же подрубаю Смарт к WiFi всё великолепно работает. Стопора нет. Если возвращаюсь на Edge, снова та же ситуация.

Бывают дни, когда и с Edgem великолепно работает. А бывают, что не работает. У друга тоже смарт, и таже прога. Так вот у нас с ним, в разное время бывает такой сбой через Edge, а бывает и совпадает.

Я никак не могу выцепить проблему. Кто может подсказать, возможные причины этого безобразия, буду благодарен.
как можно проверить, отследить, наличие данных в потоке. Приходят ли данные, возможно они повреждены. Если приходят повреждённые данные, поток считает что их вообще нет? Или он как-то по другому к ним "относится"?

strelec
Обычный пользователь
Обычный пользователь
 
Сообщения: 93
Зарегистрирован: 28.02.2009 (Сб) 22:04

Re: Сервер зависает на строке stream.read

Сообщение strelec » 27.11.2013 (Ср) 9:29

зачем заране делать Dim bytes(20480) As Byte когда ты не знаеш какой пакет прийдет?
пример из кода

Код: Выделить всё
If soc.Client.Available > 0 Then
            ' ReDim Preserve ReadBuffer(soc.Client.Available - 1)
            soc.GetStream.Read(ReadBuffer, 0, ReadBuffer.Length)
            Dim ipd As IPAddress = System.Net.IPAddress.Parse("0.0.0.0")
            RaiseEvent SocRead(ServerSocNumber, ipd, ReadBuffer)
End If

TrueTrue
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 167
Зарегистрирован: 20.05.2009 (Ср) 23:18

Re: Сервер зависает на строке stream.read

Сообщение TrueTrue » 27.11.2013 (Ср) 10:25

Ок попробую сделать как ты предлагаешь, ты думаешь это может быть причиной сбоев?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Сервер зависает на строке stream.read

Сообщение FireFenix » 27.11.2013 (Ср) 12:19

strelec писал(а):зачем заране делать Dim bytes(20480) As Byte когда ты не знаеш какой пакет прийдет?

каждый раз ReDim'ать буфер это сильно, а если учесть, что ещё gprs и телефон, то вообще Изображение

Код: Выделить всё
i = stream.Read(bytes, 0, bytes.Length)

если твой стрим - есть обёртка над Socket.Recevie, то лучше его юзать сразу

TrueTrue писал(а):ак вот прикол такой, периодически, закономерность мне выявить не удалось, когда Android работает через Edge интернет, общение клиент сервера прерывается на строке i = stream.Read(bytes, 0, bytes.Length) Тоесть, как буд-то данные клиент не посылает. Хотя я точно знаю, что данные уходят! Но на андроиде висит строка Запрос данных. Значит Андроид запрос отправил.
Когда я тут же подрубаю Смарт к WiFi всё великолепно работает. Стопора нет. Если возвращаюсь на Edge, снова та же ситуация.

Т.к. убогий grps/edge, то может отваливаться по таймауту соединения

TrueTrue писал(а):как можно проверить, отследить, наличие данных в потоке.

Снифер протокола по которым идут данные
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

strelec
Обычный пользователь
Обычный пользователь
 
Сообщения: 93
Зарегистрирован: 28.02.2009 (Сб) 22:04

Re: Сервер зависает на строке stream.read

Сообщение strelec » 27.11.2013 (Ср) 13:24

FireFenix писал(а):
strelec писал(а):зачем заране делать Dim bytes(20480) As Byte когда ты не знаеш какой пакет прийдет?

каждый раз ReDim'ать буфер это сильно, а если учесть, что ещё gprs и телефон, то вообще Изображение

я спорит не буду ))просто не понимаю как ты прочтешь с буфера bytes.Length если входящий буфер 1 к а длинна байта 20 к ?,если входящий больше чем длина байта то нормально.
а если меньше то начиная с нуля читаешь 20 к которых просто нет) не проверял но думаю должно ошибку выдаст

FireFenix писал(а):
Код: Выделить всё
i = stream.Read(bytes, 0, bytes.Length)

если твой стрим - есть обёртка над Socket.Recevie, то лучше его юзать сразу

и тут насколько я помню i дает тебе размер который ты уже принял,а заранее чтобы знать сколько ты можешь прочесть тока с помощью Available

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.11.2013 (Ср) 14:32

TrueTrue писал(а):While (i <> 0)

Не уверен, что Read обязан прочитать данные. Скорее всего он может возвращать 0 и в процессе работы.

TrueTrue писал(а):data = System.Text.Encoding.UTF8.GetString(bytes, 0, i)

Бред, поскольку байтовый буфер может прерываться внутри символа.

И вообще, используй StreamReader вместо этих извращений.

PS: Есть же нормальный цикл Do-Loop, почему While? :(

TrueTrue
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 167
Зарегистрирован: 20.05.2009 (Ср) 23:18

Re: Сервер зависает на строке stream.read

Сообщение TrueTrue » 29.11.2013 (Пт) 13:56

Как вы любите всё усложнять. :)

Уже не в первый раз так, создаю тему с вопросом, заходит несколько человек отписываются, каждый своим вариантом похвастает...
А ты так и сиди, думай, кто же в самом деле посоветовал лучший вариант.

"Не уверен, что Read обязан прочитать данные. Скорее всего он может возвращать 0 и в процессе работы."
1.Почему? А скорее, в каких случаях Read может возвратить 0?

"Бред, поскольку байтовый буфер может прерываться внутри символа."
2.Какое решение посоветуешь в данному случае, проверять чётное количество байтов в строке?

"И вообще, используй StreamReader вместо этих извращений."
3. Приведи пожалуйста хотя бы кусок кода, который не является извращением.
В Vb.NEТ я ещё очень слаб. StreamReader видел только при работе с файлами. С сетью, не видел.


4.Ты обоснуй чётко пожалуйста, чем плохо цикл While и хорош Do:Loop? точнее даже не так, чем один лучше другого?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 29.11.2013 (Пт) 14:05

TrueTrue писал(а):1.Почему? А скорее, в каких случаях Read может возвратить 0?

Если ты читаешь раньше, чем пришли данные, скорее всего. Не могу точно сказать. Но не видел никаких источников, достоверно утверждающих, что 0 невозможен.

TrueTrue писал(а):проверять чётное количество байтов в строке?

Чётное число байтов для UTF-8 - фигня. Там каждый символ занимает от 1 до 6 байт в зависимости от префикса некоторых байтов.
Это же не UTF-16.

TrueTrue писал(а):2.Какое решение посоветуешь в данному случае

Я же сказал - StreamReader. Ему в конструктор надо передать поток и кодировку.

TrueTrue писал(а):StreamReader видел только при работе с файлами. С сетью, не видел.

Там так же, но вместо строки с именем файла надо передать поток.

TrueTrue писал(а):4.Ты обоснуй чётко пожалуйста, чем плохо цикл While и хорош Do:Loop? точнее даже не так, чем один лучше другого?

Хм.. Особо ничем. Просто While уже давно считается устаревшим, непонятно зачем его вообще в VB.NET сделали.
А ещё, из Do-Loop можно сделать вечный цикл не поставив ни while, ни until :)

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 29.11.2013 (Пт) 15:06

TrueTrue писал(а):"Не уверен, что Read обязан прочитать данные. Скорее всего он может возвращать 0 и в процессе работы."
1.Почему? А скорее, в каких случаях Read может возвратить 0?

Я был неправ. 0 означает конец потока:
Stream.Read писал(а):Return Value
Type: System.Int32
The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
Формально этот метод абстрактный, следовательно это всего лишь соглашение, однако другого способа определить конец что-то не видно.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 39

    TopList