The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Socket - Передача файлов"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Socket - Передача файлов"  
Сообщение от NikR email(ok) on 27-Май-06, 04:05 
Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Socket - Передача файлов"  
Сообщение от ACCA (ok) on 27-Май-06, 11:39 
В смысле из буфера `write'? man fflush, fsync, хотя разумеется не гарантируется, что оно вообще дойдёт.

Ещё можно пользоваться `send'.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

2. "Socket - Передача файлов"  
Сообщение от smb on 28-Май-06, 01:39 
>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>

Какого еще конца файла??
Чтобы ОС отправила по TCP данные, находящиеся в output buffer(помещаются очевидно через send() | write()), надо, чтобы...На последние пакеты должно прийти подтверждение = ACK, чтобы она могла убрать отосланные и подтвержденные данные из буфера...Тогда отошлются следующие данные....(на самом деле, всё гораздо сложнее, но идея - на все данные должно прийти подтверждение - тогда начнут отправляться новые данные)

Сервер-то где подвисает?В read()?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

3. "Socket - Передача файлов"  
Сообщение от NikR email(??) on 29-Май-06, 02:00 
>>Подскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>>
>
>Какого еще конца файла??
>Чтобы ОС отправила по TCP данные, находящиеся в output buffer(помещаются очевидно через
>send() | write()), надо, чтобы...На последние пакеты должно прийти подтверждение =
>ACK, чтобы она могла убрать отосланные и подтвержденные данные из буфера...Тогда
>отошлются следующие данные....(на самом деле, всё гораздо сложнее, но идея -
>на все данные должно прийти подтверждение - тогда начнут отправляться новые
>данные)
>
>Сервер-то где подвисает?В read()?


>Да. Именно в read().

Передаётся небольшая структура. При аналезе (tcpdump..) выяснелось, что пару фрагментов
остаются на клинтской части. Обидно. Приходиться закрывать соединение, а затем вновь подключаться, тогда те куски приходят без проблем.
Идея понятна. Но как реализовать?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

4. "Socket - Передача файлов"  
Сообщение от niknik (??) on 29-Май-06, 13:48 
При организации TCP сессии даные не могут быть потеряны, т.е. пока не прийдет подтверждение о доставке предыдущего сообщения, следующее не посылается. Если связь организована c использованием UDP так он и не гарантирует доставку без ошибок.
На основе какого метода конкретно происходит общение клиента и сервера ???
Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

5. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 30-Май-06, 01:51 
>При организации TCP сессии даные не могут быть потеряны, т.е. пока не
>прийдет подтверждение о доставке предыдущего сообщения, следующее не посылается. Если связь
>организована c использованием UDP так он и не гарантирует доставку без
>ошибок.
>На основе какого метода конкретно происходит общение клиента и сервера ???

>Использую TCP соединение.
Во всех примерах клиент-сервер, которые я видел, любой обмен данными заканчивается close () или shutdown(). Понятное дело, всё работает. А вот интересно если сервер и клиент работают определённое время, за которое необходимо передать N файлов.
Как не допустить зависание сервера на read()?  

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

6. "Socket - Передача файлов"  
Сообщение от niknik email(??) on 30-Май-06, 10:27 
> Во всех примерах клиент-сервер, которые я видел, любой обмен данными заканчивается
>close () или shutdown(). Понятное дело, всё работает. А вот интересно
>если сервер и клиент работают определённое время, за которое необходимо передать
>N файлов.
>Как не допустить зависание сервера на read()?

Необходимо анализировать результат функции read(), При этом сервер может находится как в блокирущем так и не в блокирующем режиме(WAIT/NOWAIT). Для того чтобы сервер не зависал используй неблокирующий режим.  

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

8. "Socket - Передача файлов"  
Сообщение от NikR email(??) on 01-Июн-06, 01:28 
>> Во всех примерах клиент-сервер, которые я видел, любой обмен данными заканчивается
>>close () или shutdown(). Понятное дело, всё работает. А вот интересно
>>если сервер и клиент работают определённое время, за которое необходимо передать
>>N файлов.
>>Как не допустить зависание сервера на read()?
>
>Необходимо анализировать результат функции read(), При этом сервер может находится как в
>блокирущем так и не в блокирующем режиме(WAIT/NOWAIT). Для того чтобы сервер
>не зависал используй неблокирующий режим.

>Как избежать зависание я представляю. При неблокирующем режиме очень тяжело
следить за буфером, правильной его выборкой.
Я не понимаю, почему клиент остовляет часть данных у себя. И только если на его стороне закрыть соединение достовляются. Можно как нибудь без закрытия, что то типа flush()..?


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

14. "Socket - Передача файлов"  
Сообщение от Serega_S email(ok) on 05-Июн-06, 03:11 
>Передаётся небольшая структура. При аналезе (tcpdump..) выяснелось, что пару фрагментов
>остаются на клинтской части. Обидно. Приходиться закрывать соединение, а затем вновь подключаться,
>тогда те куски приходят без проблем.
>Идея понятна. Но как реализовать?

Если есть необходимость передавать данные без задержек по tcp протоколу, то необходимо отключить алгоритм Нигла в сокете. Этот алгоритм предотвращает большое количество мелких пакетов в сети, которые излишне нагружают сеть и уменьшают её пропускную способность. Этот алгоритм предотвращает посылку мелких пакетов путём ожидания добавление ещё данных в буфер, т.е. данные отсылаются одним большим куском, или же по истечении некоторого времени, которое может быть довольно большим.

Чтобы отклюсить этот алгоритм, необходимо после создания сокета функцией socket():

setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char*)&t,sizeof(t));

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

15. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 05-Июн-06, 10:23 
>>Передаётся небольшая структура. При аналезе (tcpdump..) выяснелось, что пару фрагментов
>>остаются на клинтской части. Обидно. Приходиться закрывать соединение, а затем вновь подключаться,
>>тогда те куски приходят без проблем.
>>Идея понятна. Но как реализовать?
>
>Если есть необходимость передавать данные без задержек по tcp протоколу, то необходимо
>отключить алгоритм Нигла в сокете. Этот алгоритм предотвращает большое количество мелких
>пакетов в сети, которые излишне нагружают сеть и уменьшают её пропускную
>способность. Этот алгоритм предотвращает посылку мелких пакетов путём ожидания добавление ещё
>данных в буфер, т.е. данные отсылаются одним большим куском, или же
>по истечении некоторого времени, которое может быть довольно большим.
>
>Чтобы отклюсить этот алгоритм, необходимо после создания сокета функцией socket():
>
>setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char*)&t,sizeof(t));


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

16. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 05-Июн-06, 10:27 
>>Передаётся небольшая структура. При аналезе (tcpdump..) выяснелось, что пару фрагментов
>>остаются на клинтской части. Обидно. Приходиться закрывать соединение, а затем вновь подключаться,
>>тогда те куски приходят без проблем.
>>Идея понятна. Но как реализовать?
>
>Если есть необходимость передавать данные без задержек по tcp протоколу, то необходимо
>отключить алгоритм Нигла в сокете. Этот алгоритм предотвращает большое количество мелких
>пакетов в сети, которые излишне нагружают сеть и уменьшают её пропускную
>способность. Этот алгоритм предотвращает посылку мелких пакетов путём ожидания добавление ещё
>данных в буфер, т.е. данные отсылаются одним большим куском, или же
>по истечении некоторого времени, которое может быть довольно большим.
>
>Чтобы отклюсить этот алгоритм, необходимо после создания сокета функцией socket():
>
>setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char*)&t,sizeof(t));

Это конечно всё хорошо. Но я сомневаюсь, что с подобной проблемой, боряться таким образом.
Как говориться это уже в крайнем случае. Да и идея у меня не в том что бы без задержек передовать данные, а чтоб последний фрагмент доставить.
  Спасибо.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

17. "Socket - Передача файлов"  
Сообщение от Serega_S email(??) on 07-Июн-06, 03:29 
>Это конечно всё хорошо. Но я сомневаюсь, что с подобной проблемой, боряться
>таким образом.
>Как говориться это уже в крайнем случае. Да и идея у меня
>не в том что бы без задержек передовать данные, а чтоб
>последний фрагмент доставить.

1) Если вы больше не будете передавать данные по сокету - закрываейте его - данные передадуться оставшиеся в буфере передачи.
2) Если ожидается ещё передавать данные по этому сокету - ждите ещё блока данных - он вытолкнет буфер - т.е. логика работы не нарушается.
3) Если важно именно "сразу" получить данные, т.к. следующий может прийти через 3 дня к примеру, то это как раз проблема временная, которая решается отключением алгоритма Нигла.
4) Если есть проблема в "зависании" приёмной стороны - делайте или неблокируемый сокет или же многопоточное приложение.

P.S. Какого либо решения наподобии fflush() для сокета я не знаю, если оно есть - будет интересно услышать.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

7. "Socket - Передача файлов"  
Сообщение от NuINu (??) on 30-Май-06, 16:53 
>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>

Скорее всего у теб какой то глюк или ошибка в клиенте....

А что бы сервер не зависал на чтении надо использовать select с установкой таймаута

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

9. "Socket - Передача файлов"  
Сообщение от NikR email(??) on 01-Июн-06, 01:33 
>>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>>
>
>Скорее всего у теб какой то глюк или ошибка в клиенте....
>
>А что бы сервер не зависал на чтении надо использовать select с
>установкой таймаута


Буду ждать новых предложений...

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

10. "Socket - Передача файлов"  
Сообщение от chip email(ok) on 01-Июн-06, 02:15 
>>>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>>>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>>>
>>
>>Скорее всего у теб какой то глюк или ошибка в клиенте....
>>
>>А что бы сервер не зависал на чтении надо использовать select с
>>установкой таймаута
>
>
>Буду ждать новых предложений...

Если есть возможность разместите код клиент-сервера. Это упростит задачу.


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

11. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 02-Июн-06, 02:19 
>>>>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>>>>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>>>>
>>>
>>>Скорее всего у теб какой то глюк или ошибка в клиенте....
>>>
>>>А что бы сервер не зависал на чтении надо использовать select с
>>>установкой таймаута
>>
>>
>>Буду ждать новых предложений...
>
>Если есть возможность разместите код клиент-сервера. Это упростит задачу.

Сервер принимает файл:

int filein (char *pathf,int fd) {
int n;
FILE *f;
char buf[MAX_PATCH_LEN];

if ((f=fopen(pathf,"w+"))==NULL)
  {
   return (-1);
  }
  while ((n=read(fd,&buf,sizeof(buf)))>0) {   //Здесь мы очень долго ждём
   if (fwrite(buf,1,n,f)<0)
     {    
       fclose (f);
       return (-1);
     }
  }
fclose (f);
}


Клиент использует функцию для передачи файла:

int fileto (char *pathf,int fd) {
int n;
FILE *f;
char buf[MAX_PATCH_LEN];

if ((f=fopen(pathf,"r"))==NULL)
  {
   return (-1);
  }
  
  while ((n=fread(&buf,1,sizeof(buf),f))!=NULL) {
   if (write(fd,buf,n)<0)
     {
       return (-1);
     }
  }
shutdown (fd,2);  //Если без этого, то сервер так и не получит последних данных
                  //находящихся у клиента.
}

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

12. "Socket - Передача файлов"  
Сообщение от chip email(ok) on 03-Июн-06, 15:25 
>>>>>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>>>>>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>>>>>
>>>>
>>>>Скорее всего у теб какой то глюк или ошибка в клиенте....
>>>>
>>>>А что бы сервер не зависал на чтении надо использовать select с
>>>>установкой таймаута
>>>
>>>
>>>Буду ждать новых предложений...
>>
>>Если есть возможность разместите код клиент-сервера. Это упростит задачу.
>
>Сервер принимает файл:
>
>int filein (char *pathf,int fd) {
>int n;
>FILE *f;
>char buf[MAX_PATCH_LEN];
>
>if ((f=fopen(pathf,"w+"))==NULL)
>  {
>   return (-1);
>  }

почему бы здесь не вставить select?

>  while ((n=read(fd,&buf,sizeof(buf)))>0) {   //Здесь мы очень долго ждём

может read заменить на recv/recvfrom?

>   if (fwrite(buf,1,n,f)<0)
>     {
>       fclose (f);
>    return (-1);
>     }
>  }
>fclose (f);
>}
>
>
>
>
>Клиент использует функцию для передачи файла:
>
>int fileto (char *pathf,int fd) {
>int n;
>FILE *f;
>char buf[MAX_PATCH_LEN];
>
>if ((f=fopen(pathf,"r"))==NULL)
>  {
>   return (-1);
>  }
>
>  while ((n=fread(&buf,1,sizeof(buf),f))!=NULL) {
>   if (write(fd,buf,n)<0)

write -> send

>     {
>    return (-1);
>     }
>  }
>shutdown (fd,2);  //Если без этого, то сервер так и не получит
>последних данных
>            
>      //находящихся у клиента.
>}


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

13. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 04-Июн-06, 01:12 
Спасибо.
*-
Обязательно попробую данный вариант. Но только не пойму принципиальной разници.
Разве что, send/recv использовать определённые флаги. А таимаут в select спасёт только от завизание сервером, но данные так и не дополучу.


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

18. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 09-Июн-06, 05:31 
Да, я понял Вашу идею.
Но вопрос остаётся открытым..
А именно: "Каким образом можно (без отключения алгоритма Нигла) доставить эти дурацкие данные, которые томятся у клиента" ?

Надо наверное сворачивать эту тему, а то скорее всего я Вам всем поднадоел.
Но думается проблема актуальная.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

19. "Socket - Передача файлов"  
Сообщение от Serega_S email(ok) on 09-Июн-06, 07:24 
>Да, я понял Вашу идею.
>Но вопрос остаётся открытым..
>А именно: "Каким образом можно (без отключения алгоритма Нигла) доставить эти дурацкие
>данные, которые томятся у клиента" ?
>
>Надо наверное сворачивать эту тему, а то скорее всего я Вам всем
>поднадоел.
>Но думается проблема актуальная.

Согласен, вопрос остаётся открытым. И было бы хорошо, если бы кто-нибудь на него ответил.

Хотя я не уверен, что есть средства вмешательства во внутреннюю логику tcp-протокола. Т.е. фактически дублирование алгоритма Нигла.

А гибкий механизм управления типа fflush был бы, конечно, приятен...

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

20. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 10-Июн-06, 02:17 
>А гибкий механизм управления типа fflush был бы, конечно, приятен...

Ещё один маленький вопрос.
Попытка вырубить алгоритм Нигла:

setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,(char *) &option, sizeof(option));

В результате он не отключается.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

22. "Socket - Передача файлов"  
Сообщение от serge email(??) on 11-Июн-06, 15:43 
>>А гибкий механизм управления типа fflush был бы, конечно, приятен...
>
>Ещё один маленький вопрос.
>Попытка вырубить алгоритм Нигла:
>
>setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,(char *) &option, sizeof(option));
>
>В результате он не отключается.

потому, что вы делаете что-то другое ))
нужно так:

   int on = 1;

   if (-1 == setsockopt(fd, SOL_TCP, TCP_NODELAY, (void *) &on, sizeof (on)))
        warn("setsockopt(TCP_NODELAY)");

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

23. "Socket - Передача файлов"  
Сообщение от cobold on 12-Июн-06, 03:08 
При такой постановке задачи почему бы не использовать sendfile(2) ?

>
>Сервер принимает файл:
>
>int filein (char *pathf,int fd) {
>int n;
>FILE *f;
>char buf[MAX_PATCH_LEN];
>
>if ((f=fopen(pathf,"w+"))==NULL)
>  {
>   return (-1);
>  }
>  while ((n=read(fd,&buf,sizeof(buf)))>0) {   //Здесь мы очень долго ждём
>   if (fwrite(buf,1,n,f)<0)
>     {
>       fclose (f);
>    return (-1);
>     }
>  }
>fclose (f);
>}
>
>
>
>
>Клиент использует функцию для передачи файла:
>
>int fileto (char *pathf,int fd) {
>int n;
>FILE *f;
>char buf[MAX_PATCH_LEN];
>
>if ((f=fopen(pathf,"r"))==NULL)
>  {
>   return (-1);
>  }
>
>  while ((n=fread(&buf,1,sizeof(buf),f))!=NULL) {
>   if (write(fd,buf,n)<0)
>     {
>    return (-1);
>     }
>  }
>shutdown (fd,2);  //Если без этого, то сервер так и не получит
>последних данных
>            
>      //находящихся у клиента.
>}


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

21. "Socket - Передача файлов"  
Сообщение от serge email(??) on 11-Июн-06, 15:39 
>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>

после того, как сделали send/write на отправляющей стороне, сделайте read/recv там-же. данные будут вытолкнуты из буффера и отправлены принимающей стороне.

кроме того, можно попробовать включить и сразу выключить флаг TCP_CORK, что-то типа:

    int on = 1, off = 0;

    if (-1 == setsockopt(fd, SOL_TCP, TCP_CORK, (void *) &on, sizeof(on)))
        warn("setsockopt(TCP_CORK)");

    if (-1 == setsockopt(fd, SOL_TCP, TCP_CORK, (void *) &off, sizeof(off)))
        warn("setsockopt(TCP_CORK)");

но этот способ только для Linux.

далее - философские рассуждения )
вообще, мне кажется, нужно сразу делать эти вещи в неблокирующем режиме. простота блокирующего режима - мнимая.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

24. "Socket - Передача файлов"  
Сообщение от NikR email(ok) on 13-Июн-06, 02:20 
>далее - философские рассуждения )
>вообще, мне кажется, нужно сразу делать эти вещи в неблокирующем режиме. простота
>блокирующего режима - мнимая.


Что то не слышел о TCP_CORK, но какие мои годы.
Может переводить сокет в неблокирующи, а затем обратно?
Тем самым доставлю данные.
Ну и конечно проверю Ваш метод

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

25. "Socket - Передача файлов"  
Сообщение от vlad email(??) on 16-Июн-06, 10:40 
>Аодскажите пожалуйста, какие есть способы доставки клиентом серверу данных находящихся в буфере
>передачи. А то сервер подвисает, ждёт конца файла. TCP_NONDELAY не помогает.
>

У меня аналогичная проблема решилась так:

Передающая сторона int val = 0;setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));

Принимающая сторона через select()

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру