winsock

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

winsock

Сообщение doctor_noname » 07.12.2009 (Пн) 17:21

Есть сторонний сервер, который регулярно шлёт синхропакет и данные. Пишу свой клиент на основе winsock. Синхропакет, состоящий из заголовка, служебной инфы, размера данных (в байтах) и финального сообщения получаю корректно.

Код: Выделить всё
ws.GetData AP.StartPacket, , 4
    ws.GetData AP.FPS, , 4
    ws.GetData AP.FramesDropped, , 4
    ws.GetData AP.GrabDibDataSize, , 4
    ws.GetData AP.EndPacket, , 4


Затем надо получить сами данные:
Код: Выделить всё
ws.GetData aux_str, vbString, bytesTotal
        a_Str = a_Str & aux_str
        If Len(a_Str) = AP.GrabDibDataSize Then Call CopyMemory(VarPtr(ArrivalArray(0)), StrPtr(a_Str), AP.GrabDibDataSize)


Судя по описанию протокола сервера, данные - это развертка изображения 32 битного цвета (R,G,B, пустой байт)
А я получаю в ArrivalArray что то похожее на цветовые компоненты в таком формате:
(искаженный цвет, почти пусто, искаженный цвет, почти пусто, искаженный цвет, почти пусто, пусто, пусто)
то есть цветовой массив растянут в 2 раза и искажен. Связано ли это с тем, что в строке ws.GetData aux_str, vbString, bytesTotal указываю тип данных vbString и есть ли альтернативные пути получения массивов данных через winsock (хотя не принципиально winsock) без такого извращения как формирование строки и затем copymemort?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: winsock

Сообщение Хакер » 07.12.2009 (Пн) 17:26

Затем надо получить сами данные:
Код: Выделить всё
ws.GetData aux_str, vbString, bytesTotal
        a_Str = a_Str & aux_str
        If Len(a_Str) = AP.GrabDibDataSize Then Call CopyMemory(VarPtr(ArrivalArray(0)), StrPtr(a_Str), AP.GrabDibDataSize)

Это кошмар. Никогда не используйте строковые переменные в качестве буферов для байтовых массивов. Никогда!

Судя по описанию протокола сервера, данные - это развертка изображения 32 битного цвета (R,G,B, пустой байт)
А я получаю в ArrivalArray что то похожее на цветовые компоненты в таком формате:
(искаженный цвет, почти пусто, искаженный цвет, почти пусто, искаженный цвет, почти пусто, пусто, пусто)
то есть цветовой массив растянут в 2 раза и искажен. Связано ли это с тем, что в строке ws.GetData aux_str, vbString, bytesTotal указываю тип данных vbString и есть ли альтернативные пути получения массивов данных через winsock (хотя не принципиально winsock) без такого извращения как формирование строки и затем copymemort?

О, как раз проблема в том, о чём я говорил выше. Конечно есть альтернативный путь, читай документацию по методу GetData: данные можно получать сразу в байтовый массив.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

Re: winsock

Сообщение doctor_noname » 07.12.2009 (Пн) 17:32

хмм, спасибо. Все примеры по winsock, которые видел, использовали для буферизации строку (правда им везде строки и были нужны, а не битовые массивы), в MSDN пример тоже только строковый, ну что ж, буду рыть дальше...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: winsock

Сообщение Хакер » 07.12.2009 (Пн) 17:34

Ну возможен случай, что удалённый компьютер шлёт тебе именно UCS-2-строчки. В этом случае как раз и надо использовать String-переменные. Только BytesTotal делить на 2.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

Re: winsock

Сообщение doctor_noname » 07.12.2009 (Пн) 17:37

Нет, там точно не юникод строки, а именно байтовый массив, так что воспользуюсь советом и поищу хорошее описание метода GetData

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: winsock

Сообщение Хакер » 07.12.2009 (Пн) 17:39

Я не о твоём случае, а о случае, который подразумевается под многочисленными примерами, где идёт получение в строку.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

Re: winsock

Сообщение doctor_noname » 08.12.2009 (Вт) 16:42

В условиях отсутствия нормальной документации по winsock, особенно части связанной с передачей битовых массивов, думаю возможные реализации будут интересны.

Итак, задача - передать через винсок контролл битовый массив. Проблема - документация по этой теме преимущественно ограничена приемом строковых переменных через метод getdata. При приеме строк они конвертируются в юникод, при этом происходит искажение битовых данных.

Вариант 1. Принять строку, открыть файл для записи For Binary Access и туда записать строку, при этом вроде как битовые данные будут сохранены корректно. Метод не проверял, т.к. интересует не сохранение данных в файл, а их постобработка в программе.

Вариант 2. В качестве буфера используем строку (как в первом посте), потом преобразуем её в битовый массив.

Код: Выделить всё
Dim ArrivalArray() As Byte
ArrivalArray = StrConv(a_Str, vbFromUnicode)

Метод работает, проверено.

Вариант 3. Использовать под буфер не строки, а бинарные структуры, все таки недаром же предусмотрен тип данных vbByte+vbArray в методе GetData
Проблема в том, что просто так в качестве аргумента массив или указатель на массив в этот метод не засунешь.
Нашёл упоминание об использовании для этих целей структуры SAFEARRAY, буду проверять, результаты напишу.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: winsock

Сообщение Хакер » 08.12.2009 (Вт) 16:56

Тебе надо повторять?

Зачем было писать первый и второй варианты (поганые), если выше уже было сказано, что нужно использовать третий.

Во-первых, читать для профилактики.
Во-вторых, не массив бит, а массив байт.
Во-третьих, какие всё-таки проблемы с получение массива байт
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

Re: winsock

Сообщение doctor_noname » 08.12.2009 (Вт) 17:05

бррр...всё гораздо проще, getdata нормально кушает динамические массивы, ток на статические ругается =\
Код: Выделить всё
Dim auxarr() As Byte
        ws.GetData auxarr, vbByte + vbArray, bytesTotal

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: winsock

Сообщение Хакер » 08.12.2009 (Вт) 17:09

vbByte Or vbArray правильно писать.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

doctor_noname
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 07.12.2009 (Пн) 16:39

Re: winsock

Сообщение doctor_noname » 08.12.2009 (Вт) 17:11

Хакер писал(а):Тебе надо повторять?

да, и много раз, иначе не доходит.


Хакер писал(а):Зачем было писать первый и второй варианты (поганые), если выше уже было сказано, что нужно использовать третий.
Затем что не нашел корректного описания третьего.


Спасибо.


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: Google-бот и гости: 68

    TopList