Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.03.05;
Скачать: [xml.tar.bz2];

Вниз

Особеннсть метода Socket.SendText   Найти похожие ветки 

 
zig   (2003-12-29 10:35) [0]

Выявилось вот что:
Если последовательно друг за другом вызвать два или более метода Socket.SendText то на машине-получателе при вызове метода socket.receivetext будет принята одна строка склеенная из всех строк методов SendText. Что бы эти строки как то разделить на приемной стророне пришлось делать паузу между вызовами методов SendText. Причем ни символы конца строк и перевода каретки в конце каждой отдельной строки не помогают. Причем время паузы зависит от скорости сети (чем выше скорость тем меньше время). Видимо не успев отправить первую строку и видя что уже есть на отправку следующая (в буфере) он их склеивает и посылает как одно целое.
Конешно можно нагородить на приемной стророне свой метод по расклеиванию строк, но может кто нть подскажет как разделить эти строки уже при отправке?
P.S. Есть подозрения что с методом SendBuf происходит то же самое.


 
Digitman   (2003-12-29 11:06) [1]


> Конешно можно нагородить


именно "нагородить" и будет единственно правильным решением в условиях поточного протокола, каковым является TCP-протокол, используемый упомянутыми компонентами


> P.S. Есть подозрения что с методом SendBuf происходит то
> же самое


вполне оправданы, ибо SendText() в своем теле напрямую вызывает SendBuf()


 
Новичек   (2003-12-29 11:30) [2]


> Digitman


наскока я понял ты имеешь ввиду что при отсылке через SendBuf блоки по 10 байт - на сервере при возникновении OnReceiveBuf может быть блок размером n*10 байт?


 
Digitman   (2003-12-29 11:59) [3]


> Новичек


я имею ввиду, что на сервере В ПРОИЗВОЛЬНЫЙ момент времени (разумеется - после 1-го клиентского Send"а) возникнет событие, которое просто фиксирует факт доступности некоей очередной порции данных, принятых от клиента ... их размер следует ожидать ЛЮБЫМ, от 0 до n*10 байт включительно, и никаких предположений о "целиком" пришедших "блоках" делать не следует : сколько доступно в момент события, столько и считывай recv-методом, а уж потом анализируй, к чему это относится и куда эту порцию "прилепить" (с учетом возможно уже ранее принятых "порций")

поток есть поток !!

хорошую ассоциацию кто-то тут недавно по сему поводу приводил :

вода из крана - это поток, вода может литься с переменным давлением, как это взбрендит всяким там "водоканалам" и прочим коммун.службам (от капли в сутки до ведра за секунду), но если ты решил носить воду, набираемую из-под крана только 3-х литровыми банками, то ты должен дождаться N "событий капанья" (очередная капля капнула, сколько таких капель будет - заранее неизвестно), проверить наполненность банки и только после факта ее наполнения тащить уже полную банку куда-то там, иначе ждать до потери пульса у крана, пока не "накапает" столько сколько ожидаешь


 
Новичек   (2003-12-29 12:23) [4]


> Digitman


Хорошо, но у меня такой вопрос:
Вот таже ситуация!...10 байт и тд!
Будут ли резаться мои пакеты?

Например 5 клиента шлют серверу блоки по 10 байт!
Может ли быть такое что за первую порцию придет буфер из 25 байт например (2 полных блока и половинка).. или же цельные блоки будут приходить, но склееные с другими?

И второй вопрос:
Я так понял мы говорим про неблокирующие сокеты или ???


 
Polevi   (2003-12-29 12:44) [5]

>Например 5 клиента шлют серверу блоки по 10 байт!
у каждого клиента будет свой сокет


 
Digitman   (2003-12-29 12:46) [6]


> Может ли быть такое что


да, может ... никаких предположений о размере приходящих "блоков" делать не следует ... да и приходят не "блоки" , а "капли" (см. ассоциацию про кран) : по одной или по сто сразу - неважно ... ты сам должен набирать по каплям свои банки


> мы говорим про неблокирующие сокеты или ???


про любые

разница лишь в том, что в случае блок.режима ты просто "заказываешь" у recv-ф-ций транспорта прием "полной банки" ... когда эта "банка нальется" (и нальется ли вообще), тебе заранее неизвестно : ты просто вызвал в некоем код.потоке ф-цию recv() и ждешь до одури, пока вся "банка не нальется" и ф-ция не вернет в результате тебе упр-е или не возвратит отказ из-за ошибок транспорта


 
Новичек   (2003-12-29 13:41) [7]


> Digitman


Тогда такой вопрос:
Я посылаю с клиента буфер в 10 байт! Как мне на сервере склеить его если он пришел в разных пакетах?

И как вообще узнать где там сколько байт и от кого - если там будет полная каша?


 
Digitman   (2003-12-29 14:01) [8]


> Тогда такой вопрос:
> Я посылаю с клиента


тогда контрвопрос - режим какой ? блок. или неблок. ?


 
Новичек   (2003-12-29 14:08) [9]

режим не блокирующий!

Задача например такова:
Есть очень много клиентов ну и 1 сервер:

Все "обмениваються" с сервером с помошью пакетов по 10 байт (к примеру)

Вдруг например на сервере пришел буфер из 25 байт и что дальше?

Ну допустим 10 байтные пакеты можно маркировать "от кого" например 1 байт - номер юзера!

Но как мне разобрать в каше? где из них кто? и где начало нужного клиентского пакета и где конец?

режим не блокирующий!
потому что не хочу ждать у моря погоды! :-)


 
Digitman   (2003-12-29 14:26) [10]


> Вдруг например на сервере пришел буфер из 25 байт и что
> дальше?


бери первые 10 байт ("банка") и обрабатывай их

для оставшихся 15-ти байт событие OnRead() возникнет вновь. никуда они не пропадут, так и будут ждать своей очереди на считывание тобой (включая вновь поступающие, пока ты обрабатываешь очередные считанные 10 байт)

в событии OnRead() удалось прочитать менее 10 байт, например, 5 байт ("пол-банки") ? Не беда ! запомни их где-то в своем промежуточном навопительном буфере и отдыхай-занимайся своими делами .. Как только придет ("накапает") еще какая-то порция, вновь возникнет событие OnRead() , в котором тебе нужно будет попытаться прочитать недостающие до "наполнения банки-буфера" 5 байт, дозаписать их начиная с нужной позиции в буфер и только после этого буфер обрабатывать


> можно маркировать "от кого"


не нужно их "маркировать"

2-й параметр обработчика события OnRead() и есть "маркер", отражающий контекст связи с конкретным клиентом, который послал данные и в результате чего возникло ДАННОЕ событие OnRead ... т.е. поперепутать данные, поступающие от разных клиентов, попросту невозможно - это надо еще умудриться сделать)


> где начало нужного клиентского пакета и где конец?


ну ты же наперед знаешь , что размер отдельного клиентского сообщения равен 10 байт ? Значит, прочитав полностью РОВНО 10 байт, ты и получишь ПОЛНОЕ сообщение, и очередные поступающие данные будут уже относиться к очередным сообщениям


 
Новичек   (2003-12-29 14:50) [11]

Как я понял каждый новый пакет, пришедший на сервер - будет записываться в "Банк" в конец! и на каждый блок 10 байт от клиента будет срабатывать событие ON.Read!

И что делать когда я прочитал свои 10 байт из "банка" ?
Удалить их и сдвинуть буффер на 10 байт влево?

Чтото не понимаю как с "Банком" правильно работать!


 
zig   (2003-12-29 14:53) [12]

Вообщем я понял что мораль следующая:
организуй на приемной строне свой буфер куда считывай все из сокета, а потом уж сам разбирайся в границах блоков своих данных, которые никак не коррелируются с блоками принимаемых сокетом сетевых данных. Ну вообщем то все логично и правильно. Просто я думал что это проблема не нова и ее как то решили в Борланде и включили какие то методы в свои классы. Хотя бы при передаче строк.
Придется писать самому...


 
Digitman   (2003-12-29 15:05) [13]


> zig



> я думал что это проблема не нова


это вообще не проблема и не баг - это нормальная фича и особенность TCP как такового


> ее как то решили в Борланде


ее не "решали", а реализовали (специально для бестолковых и ленивых) некое подобие "надстройки над TCP" , и это есть в компонентах NMMsg, NMStrm, IdTCPServer/Client и т.д. и т.п. ... одним словом - везде где используется TCP-протокол и есть методы, в которых вход. и исход. транспортные потоки "разбиваются" на отдельные "блоки", "сообщения", "потоки", "строки" и т.д. и т.п.

резюме простое как лапоть :

1) ленив ? используй некие "продвинутые" компоненты-надстройки над TCP-протоколом и лишайся прозрачности/гибкости управления транспортом

2) хочешь максимальной прозрачности/гибкости всего того что происходит в компоненте ? Используй либо напрямую WinsockAPI либо простую и надежно-удобную "оболочку" для WinsockAPI в виде компонентов TClient/ServerSocket

третьего не дано)

вернее, дано, но уводит оно в жуткие дебри TDI, на котором собственно и базируется подсистема Winsock) ... а оно надо нам ?)


 
Новичек   (2003-12-29 15:11) [14]


> Digitman


На мой вопрос можешь ответить?
zig-у не интересно наверно а мне интересно! :-)


 
Digitman   (2003-12-29 15:22) [15]


> Новичек (29.12.03 14:50) [11]



> в "Банк"


да не в "банк", а в "банку"))) ... это я ссылаюсь на ассоциацию с краном)


> и на каждый блок 10 байт от клиента будет срабатывать событие
> ON.Read!


неверно.
OnRead() будет срабатывать всякий раз пока в очередь поступающих данных непуста ... ты, к примеру, прочитал 5 байт, остались непрочитанными еще 2 байта - жди будущего OnRead(), оно обязательно возникнет



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.03.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.011 c
6-12474
Vilux
2003-12-28 05:47
2004.03.05
Timeout в сокетах


14-12507
Oyster
2004-02-10 15:57
2004.03.05
Собираю приколы


8-12458
LEON88
2003-10-31 00:43
2004.03.05
Программа поверх игры


1-12371
Ivolg
2004-02-25 11:42
2004.03.05
Компоненты


1-12326
vlv
2004-02-25 15:50
2004.03.05
Как определить, какая версия установлена на компьютере?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский