Потеря данных в сети или Перегрузка сети

Тема в разделе "WASM.NETWORKS", создана пользователем calidus, 11 апр 2007.

  1. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Есть такая проблема в моем приложении. Реализована передача строк и команд от сервера к клиенту.На компе у себя все работает супер !!!! Без всяких проблем ... сенд установлен в слип 10 ....когда я убераю слип 10 ....то тогда к клменту приходит только часть нужной инфы ...хотя сервер отработал все ок ....точнее не часть а 1 десятая дето ..... когда же я использую в нете ...клиент сервер на разных компьютерах...то слип 10 не помогает ....и также приходиттолько часть информации ....(передаваемая инфа обьемна ) и передача стоит в цикле ......сервер отрабатывает ок ...так как другие маленькте команыды посланные работают ок. Но инфа отправленная не дошла. В чем тут может быть дело ??? ктонибудь имел дело с алгоритмами избежания перегрузки сети ....или это что то другое ........Заранее спасибо !
     
  2. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Больше конкретики и меньше этих сраных точек.
     
  3. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    конкретно написано ....не все доходит ....с описанием ..))))))))) как делается
     
  4. ShadoWich

    ShadoWich New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2007
    Сообщения:
    35
    Конкретики нет, аффтар - пиши нормально.
     
  5. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    есть клиент сервер приложение .....посылаемые данные приходят не все ....только часть .... хотя посыл сервером весь отрабатывает ....на одном компе ..когда к се конектится все ок работает ...в интернете не доходит ....то есть посали скажем 10 строчек...пришли только 2 ...но сервер отправил все !!!! ....это только в интернете .... но если в моем сенде убрать слип 10 то тогда и на одном компьютере доходит часть ......вопрос как сделать чтоб все дошло ...алгоритм самый простой ....сенд ресив в буфера обмена и все !!!!!!!!!! ...но строки обемные по размеру ....что приводит к циклу сенд и ресив...но сенд все отработал а реив не получил часть .....не знаю как вам еще обяснить .....написано так же как в книге снэйдера про потерю информации ....))))))) самое интересное что тот кто знает о чем речь все поймет и из первого топика хахаха
     
  6. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    алгоритм Нейгла ....Ее пропускная способность обычно достаточно высока. А где-то на магистральных каналах, например, в 5 хопах от тебя случилось переполнение по суммарному объему трафика. И вот маршрутизатор копит, копит пакеты у себя в буфере (от 64 кб до нескольких Мегабайт), но если переполнение не рассосалось за скажем 5 секунд, он начинает пакеты дропать.
    И в гетерогенных сетях типа Интернета твой сетевой адаптер никогда не узнает об этом дропании, поскольку механизмы сигнализации о переполнениях еще более ли менее разработаны в рамках сетей одного протокола, типа FrameRelay, ATM Или MPLS, а вот на стыке разных канальных протоколов на сегодняшний день полный бардак.

    Путь решения этой задачи только один - от верхнего уровня, то есть пляшем от недоставки пакета. Чистый UDP вообще никогда не узнает, о том, что его пакет дропнулся из-за переполнения по трафику. TCP узнает отсутствием квитка приема. Ну и конечно же ты сам можешь что-нибудь прикрутить поверх того же UDP или даже IP с какой-нибудь лавинной отправкой (более/менее интеллектуальной конечно), а затем доотправкой недошедших пакетов на основании битов в пакете-квитке.

    я думаю что проблема в этом ..так как мелкие пакеты на ура проходят у меня
     
  7. al79

    al79 Алексей

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    133
    Адрес:
    Екатеринбург
    Когда я осваивал сеть, я также думал сеть перегружена, теряются пакеты, а когда с головой подошел к этому вопросу понял, что в сети ни чего не теряется просто надо граматно отправлять и получать пакеты.
    1. Когда ты отправляешь несколько пакетов не большой длины, это не значит что ты их получишь несколькими пакетами, ты их можешь получить одним пакетом!
    2. При отправки больших пакетов, клиент может его получить порезаным скажем по 8Кб.
    Стал учитывать эти два пункта и ни чего сейчас не теряется.
     
  8. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    calidus: Отчет о недоставке пакета идти не должен. Сам стек TCP реализован так, что без подтверждения о ПОЛУЧЕНИИ пакета отправит еще раз. После нескольких неудачных попыток должна появиться ошибка.
    Если у тебя send завершается нормально, а recv что-то не читает - значит ошибка у тебя.
     
  9. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    понятно ... этот код думаю является примером твоих слов или ?
    только сделать ресив такой .....чтоб он знал сколько ему читать ....и что следующее да ?

    ; MySend. первый параметр - буфер для отправки,
    ; второй параметр - длинна, третий параметр - сокет.
    MySend PROC StrSend : DWORD, LenStr : DWORD, clnt : DWORD
    ; edi указывает на буфер для отправки
    mov edi, StrSend
    ; ebx - сколько нужно отправить
    mov ebx, LenStr
    ; dll2 - сколько отправленно
    mov dll2, 0
    ; dll0 - тайм-аут
    mov dll0, 0
    ; Цикл отправки
    .WHILE TRUE
    mov ecx,3
    ZANOVO:
    dec eax
    ; Отправка данных
    invoke send, clnt, edi, ebx, 0
    .IF eax == SOCKET_ERROR
    cmp ecx,0
    jne ZANOVO
    .ENDIF
    ; Добавление в dll0 количества отправленных данных
    add dll0, eax
    ; Если отправленно необходимое число - выход из цикла
    mov eax, LenStr
    .BREAK .IF ( dll0 >= eax )
    ; Если тайм-аут - выход из цикла
    inc dll2
    .BREAK .IF ( dll2 >= 666 )
    ; переставить указатель на позицию данных в буфере, которые еще не отправленны
    add edi, dll0
    ; пересчитать кол-во отправляемых данных
    sub ebx, dll0
    .ENDW
    invoke Sleep,10
    ret
    MySend ENDP
     
  10. ShadoWich

    ShadoWich New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2007
    Сообщения:
    35
    Если такая ошибка, то никаких заново. За повторную передачу отвечает транспортный уровень.
     
  11. ShadoWich

    ShadoWich New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2007
    Сообщения:
    35
    dec ecx?

    короче каша в голове
     
  12. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    TCP соединение вообще говоря нужно рассматривать как поток, а не как отдельные пакеты. Соответсвенно приёмник должен быть готов к тому, что данные будут приходить совсем не теми порциями какими отправлялись, а потоком. Обычная практика - сначала сообщать размер данных, затем отсылать их. Другой подход - использовать маркер начала (или конца) пакета, т.е. некий символ/ последовательность символов, который/ая точно не встретится в данных. В простейшем случае (на блокирующих сокетах) отсылка будет выглядеть где-то так:
    Код (Text):
    1. if (send(socket, datasize, sizeof(datasize), 0)==sizeof(datasize))
    2. {
    3.     if (send(socket, data, datasize, 0)==datasize)
    4.     {
    5.         //данные успешно отправлены
    6.     }
    7. }
    Ну а принять это можно приблизительно таким кодом:
    Код (Text):
    1. if (recv(socket, &datasize, sizeof(datasize), 0)==sizeof(datasize))
    2. {
    3.      if (recv(socket, data, datasize, 0)==datasize)
    4.      {
    5.         //данные успешно приняты
    6.      }
    7. }
    8. }
    На неблокирующих (асинхронных) сокетах придётся заниматься накоплением в буфер самостоятельно.
     
  13. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Ясно )))) а еax ///описка
     
  14. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    а при этом может терятся.....если это не учитывать ?????????
     
  15. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Вообщем я стал принмать пакеты по 1024 ...просто сенд с интервалом слип 10 и принимать ресив 1024 размер .... путаница с данными ушла ....но все равно часть информации не доходит ....хотя на локалке все быстро раз и все ....в чем может быть причина ...ни какиех инноваций нет ...сенд ресив и все
     
  16. ShadoWich

    ShadoWich New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2007
    Сообщения:
    35
    пример как делать ненадо. читаем msdn:
    т.е. отсылка данных указанных обьёмом меньше чем len это не ошибка
     
  17. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    Какая часть не доходит?

    Лучше код покажи, а то гадать можно долго
     
  18. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Client
    .ELSEIF ax == FD_READ
    ;########################################################################################
    invoke SendMessage,hPROGRESS,PBM_SETSTEP,20,0
    invoke SendMessage,hPROGRESS,PBM_STEPIT,0,0
    invoke recv,sock,addr COMANDAIN,1024,0

    + функция добавления в лист вью и конек ФДРИД



    Server
    ищет файлы ....и каждый отправляет вместе с параметрами файла..это в цикле , для каждого файла сенд свой

    потом
    invoke send, client, edi,1024, 0



    на конец в листвью приходит только половина .......именно тогда когда много файлов и папок ...или когда соединение по интернету ..с разными ип ....
     
  19. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    А ты проверяешь сколько recv принимает?
    Попробуй сначала слать 4 байта - размер файла, принимать сначала 4 байта, а потом recv в цикле пока не принят размер файла.

    Ты пытаешься работать с TCP как с пакетами. Это плохо.
     
  20. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Кто то так говорит кто так .... не знаю что делать ....принимает все 1024 !!! проверено ....всегда ..не было исключений ...может быть так что так быстро шлются данные что клиент не успевает переработать все ............. хотя я думаю не в этом дело ...так как когда идет список файлов ....от А по алфавиту до Д доходит и все ....а обычно на локалке со слип 10 приходят все от А и до конца ..вот ...т.е. получается не в буфере дело .............а другой чел мне сазал что быстро шлю ...а системный буфер для приема не резиновый....и он больше не принимает ....пришеедшее ............. а как не пакетами работать если допустим слать то что в систем 32 + дата + размер ...то получается длина офигеть ...примеров не нашел .....смотрел исходники с сайта ...там все просто но не то ...