![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сокеты
DikobraZ © (2002-03-25 19:13:00)Когда посылаются данные с помощью сокетов за одно действие они склеиваются. Т.е. два сообщения объединяются в одну строку.
Как от этого избавится????
Wizard_Ex (2002-03-26 16:56:00) [1]Как вариант в той же строке передавай размер:
например послал: S:="Hi!"
передается ASendText:=Length(S)+"#"+S
Потом просто используя Pos Delete Copy получаешь длину строки и собственно саму строку, а если маленько доделать, то и разбивку остатка строки точно также (если к этой S еще одно сообщение прицепилось)
panov (2002-03-26 14:18:00) [2]>DikobraZ
Воспользуйся SendBuf и ReceiveBuf. В них будет работать, как надо.
Digitman (2002-03-26 13:02:00) [3]>DikobraZ
Для гнездовой работы со строками проще всего воспользоваться UDP-протоколом (SOCK_DGRAM) вместо SOCK_STREAM
>yaJohn
Дело не в этом. Дело в том, что в теле ReceiveText() происходит неявный вызов WinsockAPI-ф-ции recv(), одним из параметров которой требуется передать размер "порции" данных, которые нужно прочитать из приемного буфера гнезда (а любой буфер гнезда, будь он передающий или приемный - это, своего рода, очередь поточного ввода/вывода данных). Так вот размер очер. строки в этой очереди заранее неизвестен, а потому считывается вся текущая очередь и далее сканируется символ за символом, начиная с "головы", до обнаружения символа-терминатора. Все, что до терминатора, записывается в результат работы ReceiveText(), все, что после - игнорируется и отбрасывается.
DikobraZ (2002-03-26 12:45:00) [4]Я знаю, что так и должно быть. Просто мне это мешает и нужно от этого избавиться. :)
yaJohn (2002-03-26 12:34:00) [5]2 Digitman
Т.о. можно сделать вывод, что SendText & ReceiveText работают в логике PCHAR, а не String?
2 DikobraZ
Это не баг, это фича, причем описанная в документации. Вас же не удивляет, что когда вы последовательно 2 раза пишете в файл, прочитать можно все за 1 раз.
Digitman (2002-03-26 10:23:00) [6]Ошибка :
верно будет "Т.о., str примет значение "123""
Digitman (2002-03-26 10:21:00) [7]пусть передатчик выполнил последовательно 2 вызова :
SendText("123");
SendText("456");
в момент возбуждения на приемнике события OnRead вх.поток будет содержать :
$61 $62 $63 $00$64 $65 $66 $00(8 байт)
в процессе обработки OnRead при вызове приемником метода str:= ReceiveText()
1. из буфера гнезда будет выбран весьвх.поток, доступный на данный момент, т.е. все 8 байт.
2. в переменную strбудет записана строка допервого обнаруженного в потоке терминирующего символа $00, все остальное будет отброшено. Т.о., str примет значение "456", а строка, переданная вызовом SendText("456") попросту пропадет бесследно, сколько бы ни было последующих вызовов ReceiveText.
Такова в реальности логика работы ReceiveText() у компонентов, реализующих функциональность гнезд, работающих в режиме SOCK_STREAM
panov (2002-03-26 09:56:00) [8]>Digitman © (26.03.02 08:43)
А как ожидается?-)
Приходит строка, разбираем ее на подстроки, и все.
Если завершающих символов нет (разделитель), то строка сохраняется во временном буфере, ждем, пока не закончится передача строки полностью.
Или это будет выглядеть по-другому?
Digitman (2002-03-26 08:43:00) [9]Даже при таком подходе ReceiveText все равно будет работать не так, как ожидается.
panov (2002-03-26 08:37:00) [10]Например, #13#10
DikobraZ (2002-03-26 08:26:00) [11]Это какие?? #10?
panov (2002-03-25 19:29:00) [12]вставлять разделители