alteest
Гость
|
|
« : 23-06-2003 10:29 » |
|
вопрос такой: клиент-сервер, работтают и пр. в один момент сервер начинает отправлять клиенту данные. длина 40. клиент их получает и все вроде бы нормально. НО один из блоков клиент получает как 2 по 20!!! в принципе проблема не критическая - но все же где тут грабли?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 23-06-2003 14:31 » |
|
вопрос такой: клиент-сервер, работтают и пр. в один момент сервер начинает отправлять клиенту данные. длина 40. клиент их получает и все вроде бы нормально. НО один из блоков клиент получает как 2 по 20!!! в принципе проблема не критическая - но все же где тут грабли? Для потоковых соединений это вполне допустимо и стоит это учитывать.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
alteest
Гость
|
|
« Ответ #2 : 24-06-2003 09:20 » |
|
т.е. я могу отправлять любые сообщения - любой длины, а они будут приходить как бог на душу положит?
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #3 : 24-06-2003 12:04 » |
|
В зависисмоти от сети. Существует размер пакета который в сети максимальный.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Olej
Гость
|
|
« Ответ #4 : 24-06-2003 16:00 » |
|
т.е. я могу отправлять любые сообщения - любой длины, а они будут приходить как бог на душу положит? Естественно ... В TCP нет "пакетов", "сообщений" etc. - это всё осталось на уровне UDP - есть только "поток" (или потоки: передаваемый и принимаемый). К этому нужно привыкнуть ... и всё становится намного проще... Размеры же "порций", которые "проталкиваются" в TCP за один раз - зависят от текущих размеров окна передачи и окна приёма (их размеры сообщающиеся TCP стороны каждый раз координируют). Вообще, алгоритм изменения размеров окон - достаточно сложный ("медленный старт", "отсроченные подтверждения" ... etc. - разные механизмы влияют). Но, в правильно спроектированных net-приложениях, эти размеры не должны никак фигурировать и оказывать влияния.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #5 : 24-06-2003 16:03 » |
|
Нет - Олег - мне кажется ты не прав - любой снифер показывает IP пакеты. А протокол передачи именно TCP/IP Есть MTU по моему так это называется где мы утанавлмваем зависимость велична пакета от скорости сети или что-то в этом роде. Я просто счас этим уже около года не занимался, вот и названия подзабыл.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Lex
|
|
« Ответ #6 : 24-06-2003 16:13 » |
|
Так это IP пакет, в TCP. который идет поверх IP пакетов(для приложения) уже нет, есть только поток данных, как сказал Олег.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #7 : 24-06-2003 16:28 » |
|
Это когда они уже в приложении... Хотя разговор идет о приложении, но из-за разбиения внутри мелддленных сетей, могут приходить и разбитыми. Кстати еще вот вспомнил, многое зависит и от того по какому пути идет пакет. Если в дороге ему будет всречен некий участок, который будет загружен, то пакет IP будет разбит раутером и часть вполне может уйти к следующему раутеру совершенно другим путем, и приехать позже. Но это в апликации уже не видно - лирика...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Olej
Гость
|
|
« Ответ #8 : 24-06-2003 16:33 » |
|
Нет - Олег - мне кажется ты не прав - любой снифер показывает IP пакеты. А протокол передачи именно TCP/IP Есть MTU по моему так это называется где мы утанавлмваем зависимость велична пакета от скорости сети или что-то в этом роде. Я просто счас этим уже около года не занимался, вот и названия подзабыл. Нет, всё правильно - это всё абстракции разных уровней: - MTU - это относится к MAC (канальному) уровню - это физические пакеты, циркулирующие в среде...; - IP - пакеты - это транспортный уровень...; - TCP/UDP - это абстракции более высокого уровня (я здесь специально не хочу привязываться к 7-ми уровневой модели ISO, т.к. TCP/IP не соответствует ей полностью ... но это "беда" не TCP/IP, а модели ISO). Вот смотрите: тот-же UDP - здесь "сообщения", "пакеты" - но это вовсе не значит, что 1 пакет UDP соответствует 1-му пакету IP - он может быть и сегментирован, и сильно ... но это - "пакет". Любой снифер будет видеть N-пакетов IP (и он - прав!), но это - только один(!) пакет UDP, и стек IP передаст пользователю этот 1 пакет только тогда, когда придут все N IP-пакетов, и в стеке (!) будет собран (дефрагментирован) пакет UDP.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #9 : 24-06-2003 16:36 » |
|
Правильно, но все равно тогда не понятно откуда взялись те самые 20+20 = 2 пакета вместо одного, кстати и как это было определено....alteest скажи как ты опрределил , что пришло 2 пакета? При чтении из сокета ты запрашиваешь сколько :?:
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Olej
Гость
|
|
« Ответ #10 : 24-06-2003 19:44 » |
|
Правильно, но все равно тогда не понятно откуда взялись те самые 20+20 = 2 пакета вместо одного, Например: - отсылается в поток 40 байт; - окно приёма в это время равно 20 байт; - 20 байт отсылаются приёмной стороне; - read( ... 40 ... ) - читает 20 байт, имеющиеся у стека TCP/IP и возвращает значение20... - после этого чтения с пакетом ACK TCP приёмник отсылает новое значение окна приёма ... оно может стать и 200... - передающая сторона тут-же отсылает оставшиеся 20 байт... - приёмная - принимает 20 байт... Всё нормально: идёт передача данных ЧЕРЕЗ ПОТОК. Что бы постоянно не сбиваться при TCP - нужно забыть что такое "пакет", "порция" и т.д. ... это - ТРУБА через которую качаются байты ... а кто там и как крутит вентиль на этой трубе (а крутит - правила TCP!) так это нас не должно касаться.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #11 : 24-06-2003 19:54 » |
|
Возможно....возможно.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
RXL
|
|
« Ответ #12 : 25-06-2003 03:22 » |
|
Ну вот, вроде, с теорией разобрались... Только не понятно - как надо извратиться чтобы получать всего по 20 байт за раз?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #13 : 25-06-2003 03:30 » |
|
ну коммандные пакеты в моем протоколе были и по 4 байта "HELO" например
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
alteest
Гость
|
|
« Ответ #14 : 25-06-2003 10:31 » |
|
так еще раз говорю - сервак ооттсылает пакеты по 40 байт!!!!!! их идет определенное количество. клиент все пакеты получает нормально кроме одного (это не пепрвый и не последний пакет - где-то в средине). Определяю что 2 по 20 - лог смотрю, да и слиетн эти пакеты куда надо пишет, а там небольшие грабельки из-за этого получаются.
|
|
|
Записан
|
|
|
|
Olej
Гость
|
|
« Ответ #15 : 25-06-2003 15:24 » |
|
Ну вот, вроде, с теорией разобрались... Только не понятно - как надо извратиться чтобы получать всего по 20 байт за раз? Обратите внимание: большинство (все!) сервисов TCP UNIX используют текстовое содержимое (формат) данных, с разбиением на строки, а окончание запроса - 2 конца строки подряд! Это не случайно - в TCP потоке лучше всего синхронизацию данных лучше всего делать по их содержимому.
|
|
|
Записан
|
|
|
|
Olej
Гость
|
|
« Ответ #16 : 25-06-2003 15:30 » |
|
так еще раз говорю - сервак ооттсылает пакеты по 40 байт!!!!!! их идет определенное количество. клиент все пакеты получает нормально кроме одного (это не пепрвый и не последний пакет - где-то в средине). Определяю что 2 по 20 - лог смотрю, да и слиетн эти пакеты куда надо пишет, а там небольшие грабельки из-за этого получаются. "так ещё раз говорю" ... в TCP нет пакетов, и то, что "сервак ооттсылает пакеты по 40 байт!!!!!!" - это ВАМ кажется, что он отсылает, это ВЫ write() написали и успокоились. Соединение TCP (стек TCP/IP) имеет право отсылать из передаваемых вами write() байт столько - сколько ОН САМ сочтёт целесообразным!
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #17 : 25-06-2003 15:34 » |
|
Да и кстати - написать цикл приема всех нужных байт, а не ориентироваться на принятые один раз - ИМХО дело 2 секунд.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Olej
Гость
|
|
« Ответ #18 : 25-06-2003 22:42 » |
|
Да и кстати - написать цикл приема всех нужных байт, а не ориентироваться на принятые один раз - ИМХО дело 2 секунд. Да, вот я к этому всё и веду... Только, вы должны знать: - сколько байт у вас будет ссобщение; ... или ещё лучше: - использовать ограничитель тела сообщения (а ещё точнее - "разделитель").
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #19 : 25-06-2003 23:36 » |
|
На крайняк CRC простейшее...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
alteest
Гость
|
|
« Ответ #20 : 26-06-2003 10:20 » |
|
Да и кстати - написать цикл приема всех нужных байт, а не ориентироваться на принятые один раз - ИМХО дело 2 секунд. дык, я это уже сделал. ладно - согласен, что написав "сервак отправляет пакеты" - я дал маху. но я спрашивал. "Почему клиент читает ввсего 20 байт, когда я ему говорю - читать 40?". и никакие маршрутизаторы - тут не при чем, потому что проверял на vmware - все на одной маашине, просто сервак пашет под одной ОС, клиент - под другой. и баг вылазит, постоянно?! (клиент кстати - виндузный)
|
|
|
Записан
|
|
|
|
sss
Специалист
Offline
|
|
« Ответ #21 : 04-07-2003 04:49 » |
|
Попробуй проверить буфер который отправляешь. Там может быть такое, что поделит его (например /0). А вообще еще можно поэксперементировать с задержкой на чтение сетевого стека (потоковый не так ли ?) он :!: должен СКЛЕЕВАТЬСЯ.
|
|
|
Записан
|
while (8==8)
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #22 : 06-08-2003 22:04 » |
|
"Почему клиент читает ввсего 20 байт, когда я ему говорю - читать 40?".
клиент читает ровно столько, сколько есть во входном буфере TCP и соответственно если он читает 20 байтов, то во входном буфере находится 20 байтов, а теперь почему там 20 байтов, а не 40. Как совершенно верно заметил Olej "так ещё раз говорю" ... в TCP нет пакетов, и то, что "сервак ооттсылает пакеты по 40 байт!!!!!!" - это ВАМ кажется, что он отсылает, это ВЫ write() написали и успокоились.
Соединение TCP (стек TCP/IP) имеет право отсылать из передаваемых вами write() байт столько - сколько ОН САМ сочтёт целесообразным!
если функция write вернула 40 это не значит что было отправлено 40 байт данных (TCP может задержать отправку данных на какое-то время => привыходе из write может получиться, что не отправлено ни байта!!! , а может быть отправлено например 20 байтов, а спустя какое-то время остальные 20, между прочим TCP мог ды вообще доставить вам данные ПОБАЙТНО т.е. при вызове recv(...40...) на клиенте вы бы считывали ОДИН!!! байт и это корректная работа TCP) А если при приеме данных вы хотите считывать 40 байтов то энто делается так Socket socket; int flags; int length = 40; // но это не обязательно int success_recv = 0; int result = 0; char * buffer = new char[length]; // не хорошо но для примера сойдет while (need_recv < length) { result = recv(socket, buffer + success_recv, length - success_recv, flags); //..... обработка ошибок success_recv += result; } // используем buffer delete []buffer; И это все как уже говорилось надо делать в отдельном потоке (потому как сокет блокирующий)
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Asan
Гость
|
|
« Ответ #23 : 07-08-2003 12:49 » |
|
Вообще-то, функция write (или send) просто помещает переданые ей для отпраки данные во внутренний буфер TCP и сразу возвращает управление. Что дальше будет с этими данными - это уже задача TCP. Тоже самое и read (recv) - если есть, что читать из буфера, она читает, что там есть. И не значит, что если ты сказал recv(sock, buffer, 100, ..), она тебе прочитает 100 байт. Сколько есть, столько и прочитает. От этого и надо плясать.
|
|
|
Записан
|
|
|
|
|