информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Крупный сбой Azure и других сервисов... 
 Серьезный сбой AWS положил множество... 
 Фишинговая атака на Python-разработчиков 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Попробую 10.07.03 13:39  Число просмотров: 1285
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Тут проблемка есть...
>
> Написал я сервер маленький, шлю файл через сокет..
>
> 1. создаю сокет
> 2. законектился
> 3. начинаю передавать данные
Как передаешь, куском или по частям? Хотя если части большие, это вроде бы не имеет разницы.

> если файл больше 100 кил, он почему-то полностью не доходит
> до клиента,
> посмотрел, сервер отправляет полность, а вот доходить не
> доходит...
В каком смысле не доходит. У TCP есть контроль доставки. Так что если все отослано, все и будет получено или будет перепосылаться пока не надоест

> В чем баг?
>
> Сокет не блокирующий (пробовал переводил в блокирующий
> режим нифига
> не помогает)... Если после отправки порции ставлю
> sleep(100); файл доходит.. Но тогда получается, что буфер
> сокета не успевает очистится, а я уже туда новую партию
> данных пихаю..
Буфер можно смотреть getsockopt-ом с SO_RCVBUF или SO_SNDBUF. Вот только если буфера не хватит, send() будет блокироваться до тех пор, пока все не отошлется и не подтвердится, так что за буфер не боись. Возможно тебя задерживает Nagle Algorithm - он задерживает (5 пакетов в секунду), а ты тем временем делаешь closesocket или shutdown и все теряется. В этом случае смотри на setsockopt с SO_LINGER - тут можно выставить задержку закрытия сокета после вызова close, необходимую для отправки оставшихся в буфере данных (ну и попутно задать таймаут на блокирование самого close-а)

> Как тогда узнать сколько в буфере места ?
Вроде никак (по крайней для мере send буфера). Вызов send не вернется пока места не станет хватать, но данные не сдропятся - не боись :-)

>
> Сокеты не Delphi`ские, а виндовые... (ну там connect(),
> select() и т.д.)
>
> Помогите у кого опыт есть!!!!
<programming>
Блин подсобите с сокетами !!!! 10.07.03 10:24  
Автор: Darkhelmet Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Тут проблемка есть...

Написал я сервер маленький, шлю файл через сокет..

1. создаю сокет
2. законектился
3. начинаю передавать данные

если файл больше 100 кил, он почему-то полностью не доходит до клиента,
посмотрел, сервер отправляет полность, а вот доходить не доходит...

В чем баг?

Сокет не блокирующий (пробовал переводил в блокирующий режим нифига
не помогает)... Если после отправки порции ставлю sleep(100); файл доходит.. Но тогда получается, что буфер сокета не успевает очистится, а я уже туда новую партию данных пихаю..

Как тогда узнать сколько в буфере места ?

Сокеты не Delphi`ские, а виндовые... (ну там connect(), select() и т.д.)

Помогите у кого опыт есть!!!!
цикл выборки должен быть такой: 10.07.03 15:50  
Автор: PS <PS> Статус: Elderman
Отредактировано 10.07.03 15:55  Количество правок: 1
<"чистая" ссылка>
Идея такая, на псевдокоде:

string globalBuffer;
char buffer[1024];

if( select( socket, 0, 0, tout ) )
{
    int ret = recv( socket, buffer, 1024, 0 );
    if( ret == 0|ret == ERROR )
    {
       // все плохо
    }
    else
    {
        for( int i  = 0; i < ret; i++ )
             globalBuffer += buffer[i];
    }
}


---

И так "бесконечно". Прверяешь на готовность - вычитываешь, проверяешь - вычитываешь...
Далее в другом потоке, либо здесь же можно сделать "разбор пакета". Тебе желательно, в начале каждого пакета передавать его длинну (лучше в сетевом формате). Потом ты бежишь по этому globalBuffer и выбираешь пакеты. если пакет еще не полный, то ничего не делаешь, если пакет уже дошел весь - перекидывешь в сторадж готовых пакетов, а из globalBuffer удаляешь.
Такой алгоритм разграничивает для тебя прием данных из сокета и прием прикладных пакетов. Тебе не придется забивать голову всякими "недошедшими данными" и прочей лабудой. Так что если у тебя в коде есть ошибка, то ты найдешь её гораздо быстрей.

И еще, если два твоих узла находятся в одной подсети, то никаких "странных" ситуаций быть не должно. Если между вами хрен знает сколько непонятно как работающих узлов, то возможны "странности". например исходящая очередь сокета будет пополнятся, а уходить из неё ничего не будет, причем о разрыве соединения тебе не скажут (вернее скажут, но скорей всего сначала ты получишь ошибку переполнения буфера сокета). Почему так происходит можно почитать в других темах.

Чуть не забыл :) Ты когда send делаешь - проверяешь количество ушедших данных ?
Цикл должен быть такой:

string yourBuffer;
int size = yourBuffer.size();
int pos = 0;

while( size > 0 )
{
int ret = send( yourBuffer.c_str() + pos, size );
size -= ret;
pos += ret;
}
Попробую 10.07.03 13:39  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Тут проблемка есть...
>
> Написал я сервер маленький, шлю файл через сокет..
>
> 1. создаю сокет
> 2. законектился
> 3. начинаю передавать данные
Как передаешь, куском или по частям? Хотя если части большие, это вроде бы не имеет разницы.

> если файл больше 100 кил, он почему-то полностью не доходит
> до клиента,
> посмотрел, сервер отправляет полность, а вот доходить не
> доходит...
В каком смысле не доходит. У TCP есть контроль доставки. Так что если все отослано, все и будет получено или будет перепосылаться пока не надоест

> В чем баг?
>
> Сокет не блокирующий (пробовал переводил в блокирующий
> режим нифига
> не помогает)... Если после отправки порции ставлю
> sleep(100); файл доходит.. Но тогда получается, что буфер
> сокета не успевает очистится, а я уже туда новую партию
> данных пихаю..
Буфер можно смотреть getsockopt-ом с SO_RCVBUF или SO_SNDBUF. Вот только если буфера не хватит, send() будет блокироваться до тех пор, пока все не отошлется и не подтвердится, так что за буфер не боись. Возможно тебя задерживает Nagle Algorithm - он задерживает (5 пакетов в секунду), а ты тем временем делаешь closesocket или shutdown и все теряется. В этом случае смотри на setsockopt с SO_LINGER - тут можно выставить задержку закрытия сокета после вызова close, необходимую для отправки оставшихся в буфере данных (ну и попутно задать таймаут на блокирование самого close-а)

> Как тогда узнать сколько в буфере места ?
Вроде никак (по крайней для мере send буфера). Вызов send не вернется пока места не станет хватать, но данные не сдропятся - не боись :-)

>
> Сокеты не Delphi`ские, а виндовые... (ну там connect(),
> select() и т.д.)
>
> Помогите у кого опыт есть!!!!
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach