цикл выборки должен быть такой:10.07.03 15:50 Число просмотров: 1335 Автор: 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;
Написал я сервер маленький, шлю файл через сокет..
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;
> Тут проблемка есть... > > Написал я сервер маленький, шлю файл через сокет.. > > 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() и т.д.) > > Помогите у кого опыт есть!!!!