Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.133.228] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
использую блокирующие сокеты в клиенте и IOCP на сервере и клиент и сервер в локальной сетке.
создание сокета: ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; m_socket = WSASocket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol, NULL, 0, 0); отправка данных на стороне клиента: WSABUF dataBuf; dataBuf.len = bytesToSend; dataBuf.buf = (CHAR*)mSendBuffer; int rc = WSASend( m_socket, &dataBuf, 1, &sendBytes, 0, NULL, NULL ); размер каждого пакета 2072 байта клиент шлет данные непрерывно. По логике вещей если сокет блокирующий то WSASend вернет значение или если ошибка в сокете или данные реально отправлены. В итоге у меня WSASend наглухо виснет ровно на 70м блоке данных Счетчик принятых пакетов на сервере показывает три принятых. Если после WSASend поставить Sleep( 100 ) то все идеально работает. раскурить где собако порылась не получается. нужен хелп |
Сообщ.
#2
,
|
|
|
progman
WireShark'ом смотрел, какие пакеты посылаются и доходят ли они? |
Сообщ.
#3
,
|
|
|
progman
Ты по факту завалил датой тот буфер памяти, отведенный для сокета; Добавлено работает FlowControl |
Сообщ.
#4
,
|
|
|
Странное семейство адресов.
Цитата progman @ hints.ai_family = AF_UNSPEC; Все дальнейшее: Цитата progman @ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; просто вопиет о семействе AF_INET. Цитата progman @ размер каждого пакета 2072 байта клиент шлет данные непрерывно. В итоге у меня WSASend наглухо виснет ровно на 70м блоке данных Счетчик принятых пакетов на сервере показывает три принятых. Если после WSASend поставить Sleep( 100 ) то все идеально работает. раскурить где собако порылась не получается. Шлет данные непрерывно - это в цикле что ли? Ну и самое главное на мой взгляд. Собака порылась в размере буфера отправки сокета клиента. Модуль TCP просто не успевает отослать все из буфера - или в сети затор, или коллизия, или в карточке буфер забит или просто еще чего - ну не успел просто. Такие ситуации встречаются сплошь и рядом. Потому слип и решает все проблемы. Значит или надо поиграть размером буфера отправки SO_SNDBUF - а он по умолчанию очень небольшой, или придерживать отправу на пару сотен милисекунд. Добавлено Цитата nemez @ Ты по факту завалил датой тот буфер памяти, отведенный для сокета; Ну во,пока я тут расписывался, ответ уже пришел,блин |
Сообщ.
#5
,
|
|
|
разобрался.
Слишком большой блок данных шлю для тестов и не учел что CP может не принять его полностью за один вызов WSARecv в реальном сервере больше 16 байт в блоке не бывает а я 4 кило пуляю ) В общем сбилась система чтения размера следующего блока - чтение самого блока и подвисло все. |
Сообщ.
#6
,
|
|
|
Честно говоря, мало что понял Виснет то send()на клиенте. А он к серверу никаким боком. Или и на сервере были проблемы?
Впрочем уже не суть. Работает. |
Сообщ.
#7
,
|
|
|
Цитата Oleg2004 @ Честно говоря, мало что понял Виснет то send()на клиенте. А он к серверу никаким боком. Или и на сервере были проблемы? Впрочем уже не суть. Работает. У меня сначала шлется 4 байта размер блока потом сам блок На одном из блоков вместо 2048 байт тела блока было прочитано только 1456 - я этот нюанс не учел и считал что блок прочитан полностью и следующие 4 байта в потоке это размер уже следующего блока. А так как клиент слал массивы по 2048 байт забитые нулями, то в итоге сервер после 1456го байта прочитал 4 нуля как размер следующего блока на приемку и стал бесконечно читать из потока по 0 байт А тестовый клиент не мог отправить данных больше чем размер буфера ну и вставал колом в ожидании когда сервак разгребет наваленные данные.. |
Сообщ.
#8
,
|
|
|
Ну теперь более менее понятно. Сервер не может отослать АСК на клиент, и клиент вис.
Ну а все таки как насчет AF_UNSPEC? к чему такой изврат? |
Сообщ.
#9
,
|
|
|
progman
так должно быть ибо такая архитектура систем. Он не стал колом, а стал ждать когда твой клиент соизволит от сервера забрать данные. У тебя еще есть один серьезный прокол по теме - тебе нужно в цикле, отправлять данные пока они не будут отправлены все. int rc = WSASend( m_socket, &dataBuf, 1, &sendBytes, 0, NULL, NULL ); не покатит, rc - по факту количество байт или sendBytes - количество байт, реально отправленных твоим сендом. Т.е. ты можешь оправить 2048 байт, а твой сенд вернет тебе 25 байт с положительным результатом. Задача такова - отправлять данные циклично, т е если отправлен чанк - отправлять пока не уйдут дети в школу, все 2048 байт. Либо использовать протоколы более высокого уровня для передачи даты аля http |
Сообщ.
#10
,
|
|
|
Цитата nemez @ progman так должно быть ибо такая архитектура систем. Он не стал колом, а стал ждать когда твой клиент соизволит от сервера забрать данные. У тебя еще есть один серьезный прокол по теме - тебе нужно в цикле, отправлять данные пока они не будут отправлены все. int rc = WSASend( m_socket, &dataBuf, 1, &sendBytes, 0, NULL, NULL ); не покатит, rc - по факту количество байт или sendBytes - количество байт, реально отправленных твоим сендом. Т.е. ты можешь оправить 2048 байт, а твой сенд вернет тебе 25 байт с положительным результатом. Задача такова - отправлять данные циклично, т е если отправлен чанк - отправлять пока не уйдут дети в школу, все 2048 байт. Либо использовать протоколы более высокого уровня для передачи даты аля http Это я как раз учитываю. и шлю пока не отправится всё |
Сообщ.
#11
,
|
|
|
progman
Если из отправленных 2048 получено 1456 (а это как раз сегмент даты впихиваемый в 1500 байт физического пакета) - значит либо ты остающиеся байты прохлопал в процессе передачи, либо оти ушли в плановые страны на этпае затыка со стороны клиента; Лучший вариант для понимания происходящего в канале - wireshark. Битва экстрасенсов это здорово, а реальное понимание - оно необходимо Цитата Oleg2004 @ Ну а все таки как насчет AF_UNSPEC? Oleg2004 там недоось винда - ей параллельно, можно писать все что хочешь, и оно будет работать. Правда, непонятно как. Но будет |
Сообщ.
#12
,
|
|
|
Цитата nemez @ progman Если из отправленных 2048 получено 1456 (а это как раз сегмент даты впихиваемый в 1500 байт физического пакета) - значит либо ты остающиеся байты прохлопал в процессе передачи, либо оти ушли в плановые страны на этпае затыка со стороны клиента; Лучший вариант для понимания происходящего в канале - wireshark. Битва экстрасенсов это здорово, а реальное понимание - оно необходимо Ничего я не прохлопал. недостающие 592 читаются следующим запросом WSARecv |
Сообщ.
#13
,
|
|
|
Цитата nemez @ Если из отправленных 2048 получено 1456 (а это как раз сегмент даты впихиваемый в 1500 байт физического пакета) Если точнее, то 1460 байтов. Цитата nemez @ там недоось винда - ей параллельно, можно писать все что хочешь, и оно будет работать. Правда, непонятно как. Но будет Но я бы все равно предпочел точность выбора семейства. ТСР никогда в моем представлении не было "неспециализированным" протоколом. Кстати, не вредно бы было глянуть на MTU системы или рутера. И конечно я бы выбирал такие объемы передачи (блоки), которые точно влазят в один IP-пакет. Для пущей вящности. |
Сообщ.
#14
,
|
|
|
Цитата progman @ Ничего я не прохлопал. недостающие 592 читаются следующим запросом WSARecv ну так система может разбивать данные на произвольные чанки, хоть по одному байту. Нужно или писать самому более высокоуровневый протокол (изобретать велосипед). Либо испльзовать уже готовый - а ля telnet, HTTP и т.д. Ну у нас по классике - костыли и велосипеды. Костыль - это таймаут после отправки, между слов говоря. Цитата Oleg2004 @ которые точно влазят в один IP-пакет ну это колхозинг. Нас не должно интересовать как там оно под капотом работает. Хочу я передавать по 5К дату - мое право, ибо TCP - потоковый протокол. Мы не обязаны вмещать дату в одну датаграмму, да и прямое предназначение TCP - контроль этой самой передачи. 5-10-50-100 - любого количества килобайт-мегабайт |
Сообщ.
#15
,
|
|
|
Цитата nemez @ ну это колхозинг. Нас не должно интересовать как там оно под капотом работает. Хочу я передавать по 5К дату - мое право, ибо TCP - потоковый протокол. Мы не обязаны вмещать дату в одну датаграмму, да и прямое предназначение TCP - контроль этой самой передачи. 5-10-50-100 - любого количества килобайт-мегабайт Ну с этим никто не спорит. Я где нибудь сомневался в потоковости ТСР? Просто если есть возможность - почему бы и нет? Особенно в связи с серверным взаимодействием, когда команды отдельно, а блоки данных - отдельно... Но...хозяин - барин. |