отправка и приём данных через сокет

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

отправка и приём данных через сокет

Сообщение Sun07 » 13.09.2006 (Ср) 2:01

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

Private Type struUDP
x1 as long
x2 as string*4
x4 as integer
x3 as string
end Type
плюс неопределённый размер данных в виде байтового массива (или в виде чего лучше организовать?). Каким образом это все лучше передавать и принимать? Опишите хотя бы словами, не обязательно кодом. Структуру при передаче не воспринимает. У меня UDP протокол.

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 13.09.2006 (Ср) 2:42

CopyMemory - поможет для упаковки udt в массив и наоборот
:idea:

и если уж без UDT никак то почему + массив
почему бы массив не в UDT :arrow: меньше парится будеш
Dmitrich

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 9:14

а как? Размер массива не постоянен. И как массив описывается в UDT?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 13.09.2006 (Ср) 10:09

Лучше изменить структуру struUDP так:
Код: Выделить всё
Private Type struUDP
    x1 as long
    x2 as string*4
    x4 as integer
    strlen as long
    byteslen as long
end Type
Тогда у тебя получится заголовок фиксированной длины, хранящий размер строки x3 и размер байтового массива. При составлении пакета ковертируешь struUDP и строку в байтовые массивы, и слепляешь все три массива в один. При получении массива берешь из начала кусок равный длине struUDP, пихаешь в соответствующую переменную, а из нее получаешь длины строки и байтового массива и разбираешь полученный пакет на куски окончательно.

Так как протокол udp не гарантирует доставку данных, то перед разбивкой проверяй размер полученного массива на превышение минимального размера - размера структуры struUDP, а потом на = len(struUDP) + struUDP.strlen + struUDP.byteslen, иначе copymemory обрушит прогу. Как раз на отсутствии таких проверок зиждется определенное количество виндовских багов, которым скармливают битые пакеты в надежде обрушить какой-нибудь сервис.
Последний раз редактировалось Antonariy 13.09.2006 (Ср) 10:31, всего редактировалось 1 раз.
Лучший способ понять что-то самому — объяснить это другому.

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 10:29

так протокол UDP не гарантирует доставку пакета, а целостность пакета гарантирует (я спрашивал здесь уже за это, и, вроде Тёмыч, мне подтвердил), но в принципе можно проверить по длине. А как писать для отправки массива x(maxIdx) в send (я имею ввиду winsock контрол)?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 13.09.2006 (Ср) 10:33

Dim x() as Byte
Winsock1.Send x
Лучший способ понять что-то самому — объяснить это другому.

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 17:40

Antonariy, всё работает, спасибо!

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 13.09.2006 (Ср) 18:09

to: Sun07

я рад что у тебя все работает :)

если не отвлекаю, это для моего понимамия :arrow:

если массив динамический то предпологается что размер данных заранее не известен, т.е это может быть как 512б так и 64кв и.т.д.

значит здесь мы спихиваем всю работу системе

целостнось пакета гарантируется
доставка пакета не гарантируется

вероятно при большом размере данных будет много пакетов, тогда потеря одного пакета приведет потере всех данных :?:

я прав. понимаю или ?
Dmitrich

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.09.2006 (Ср) 18:21

Dmitriy2003, UDP-пакеты не фрагментируются
Изображение

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 13.09.2006 (Ср) 18:26

OK.Пасиб.
Dmitrich

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 19:23

а вот ещё вопрос - можно число типа Long или строковую переменную занести в байтовый массив спец. оператором VB (не используя CopyMemory)?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 13.09.2006 (Ср) 20:51

Строку можно.
Число нельзя.
Lasciate ogni speranza, voi ch'entrate.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.09.2006 (Ср) 20:53

Думаю, можно и через LSet, и через мои прозрачные указатели.
Формально, это не CopyMemory.
Изображение

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 21:18

Как можно строку присвоить байтовому массиву одним оператором? Как определить программно тип числа (long, string)?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.09.2006 (Ср) 21:56

1) оператор =
2) чего? какой, по-твоему, тип у числа 123?
Изображение

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 13.09.2006 (Ср) 22:36

1. Если я хочу присвоить строку побайтно байтовому массиву x(100) начиная с x(4), разве пройдёт x(4) = str1?
2. Ну ошибся, тип переменной хотел узнать.

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 14.09.2006 (Чт) 1:12

еще про сокеты

UDP DataArrival 8192 bytes -> а если больше в пакете то режет

sckMsgTooBig 10040 Das Datagramm ist zu groß für den Puffer und wird abgeschnitten.

может есть какой способ увеличить размер буффера ?
Dmitrich

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 14.09.2006 (Чт) 1:26

а зачем? какой бы буфер большой не был, всё равно попадутся данные, которые придётся резать. Хочется узнать ответ на свой вопрос:
1. Если я хочу присвоить строку побайтно байтовому массиву x(100) начиная с x(4), разве пройдёт x(4) = str1?

На вопрос 2 ответ нашёл - VarType() и TypeName().

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.09.2006 (Чт) 1:29

Нет, разве не пройдёт. И хорошо.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 14.09.2006 (Чт) 1:36

1. Если я хочу присвоить строку побайтно байтовому массиву x(100) начиная с x(4), разве пройдёт x(4) = str1?


Ты же сам знаеш ответ зачем спрашиваеш?

x(4) =елемент массива значит
если str=absdfff
то результатом операции х(4)=str1 будет присвоение значения елемну массива с индексом 4 значения переменной str1
проще говоря ошибка

почему не хочеш CopyMemory использовать. :?:

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


если бы можно было до 24 кб увеличить то резать не пришлось-бы.
в сети где все карты гигабитные я думаю что 8 что 24 не принципиально
Dmitrich

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 14.09.2006 (Чт) 1:50

потому что Тёмыч сказал, что можно без CopyMemory присвоить оператором "=", зачем терзать CopyMemory, когда есть вариант проще. Да и знать надо.

я думаю, что контрол Винсок не позволит увеличить буфер. Вот если сокет создавать через API, то там есть где разгуляться. Может я и не прав.

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 14.09.2006 (Чт) 4:34

потому что Тёмыч сказал, что можно без CopyMemory присвоить оператором "=", зачем терзать CopyMemory, когда есть вариант проще. Да и знать надо.


ну да так и есть

Код: Выделить всё
dim ab() as byte: ab= StrConv("Hallo!",vbFromUnicod)
будет работать


зачем терзать CopyMemory


если на твои посты смотреть ты ее все равно терзаеш :)
Dmitrich

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.09.2006 (Чт) 5:20

Ещё раз для Dmitriy2003: UDP-пакеты не фрагментируются. Если пакет слишком большой, он просто выбрасывается. И всё.
Изображение

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 14.09.2006 (Чт) 12:29

tyomitch писал:

Ещё раз для Dmitriy2003: UDP-пакеты не фрагментируются. Если пакет слишком большой, он просто выбрасывается. И всё.


Это мы уже обсуждали.

Протокол IP получает информацию для передачи от протоколов TCP/UDP расположенных по сравнению с ним на более высоком уровне.(см. Модель OSI)

Итак IP дейтаграммы фрагментируются.

Так вот каким образом IP собирет дейтаграммы мне не интересно, справляется он с этим вполне неплохо. Все что я хочу спихнуть часть работы этому самому IP протоколу.

Чтое ему нужно RAM, широкополосный канал ? - пожалуста. :)

если размер буффера UDP можно было-бы увеличить, мой алгоритм от этого только выиграл-бы.

Вопрос :?: КАК ? :)
Dmitrich

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 14.09.2006 (Чт) 13:37

Код: Выделить всё
dim ab() as byte: ab= StrConv("Hallo!",vbFromUnicod)


мда.. Хотел добавить одним махом строку в уже заполненный частично байтовый массив начиная с определённого индекса (например, с x(4)), но при таком раскладе придётся в цикле присваивать x(4)=ab(0), x(5)=ab(1) ... Тогда уж сразу в цикле вырезать побайтно байты строки и присвоить их Ascii переменным массива от x(4) - вроде строка ab= StrConv("Hallo!",vbFromUnicod) так и делает. Не повезло опять :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.09.2006 (Чт) 13:42

Sun07, а тебе не приходит в голову, что если написать: dim ab() as byte: ab= StrConv("xxxxHallo!",vbFromUnicod), то строка ляжет в массив как раз с индекса 4? а после этого можно заполнить элементы с младшими индексами.
Изображение

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 14.09.2006 (Чт) 13:42

Если хочешь извращений, то используй CopyMemory. Вставит в любое места массива.
Lasciate ogni speranza, voi ch'entrate.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 14.09.2006 (Чт) 13:46

Sun07 а с CopyMemory не судьба договориться?

Код: Выделить всё
CopyMemory x(4), s, Len(s) ' возможно стоит уточнить нюансы
Весь мир матрица, а мы в нем потоки байтов!

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 14.09.2006 (Чт) 14:32

Но если у тебя личная неприязнь к CopyMemory, то вот тебе еще одно небольшое извращеньице :wink:
Код: Выделить всё
Private Function Concat(arr1() As Byte, arr2() As Byte)
    Concat = StrConv(StrConv(arr1, vbUnicode) & StrConv(arr2, vbUnicode), vbFromUnicode)
End Function
Лучший способ понять что-то самому — объяснить это другому.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.09.2006 (Чт) 15:32

Sun07 писал(а):я думаю, что контрол Винсок не позволит увеличить буфер. Вот если сокет создавать через API, то там есть где разгуляться.

Угу. WSASocket принимает WSAPROTOCOL_INFO, там есть поле dwMessageSize.
Грузите апельсины бочками.
Изображение

След.

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

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

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

    TopList