Re: sendfile system call in FreeBSD

From
Valentin Davydov (2:5020/400)
To
Andrey Ushakov (2:5054/37.63)
Date
2006-11-20T12:29:56Z
Area
RU.UNIX.BSD
From: Valentin Davydov <val@sqdp.trc-net.co.jp>

>   From: "Andrey Ushakov" <michaele@mail.yar.ru>
>   Date: Sun, 19 Nov 2006 20:41:24 +0000 (UTC)
>
>Вроде подразобрался, и увидел проблему с использованием recv() и sendfile() в
>связке.
>
>У меня в проге такой код
>У клиента:
>while(rc != -1 && filesize > 0)
>{
>rc = sendfile(fd, s, offset, 0, (struct sf_hdtr *) NULL, &sbites, 0);
>filesize -= sbites;
>offset += sbites;
>}
>Слизал из FTPD.C =)
>
>У сервера:
>if((rc = recv(s1, buf, sizeof(buf), 0)) < 0)
>{
>perror("recv error");
>exit(1);
>}
>
>Если в вызове recv() оставить 0, то работать будет, но с очень маленькими
>файликами. Я ставил вместо 0 MSG_WAITALL и убедился, что проблема в recv() она
>возвращает управление до того как будет послан весь файл.

man recv
     The receive calls normally return any data available, 
     up to the requested amount, rather than waiting for receipt of the full
     ^^^^^^^^^^^^^^^^^^^^^^^^^^
     amount requested;

То есть recv() у тебя получает sizeof(buf) данных и с чувством выполненного
долга сыто отваливается.

>Соответственно в
>клиенте имеем -1 и errno = 32
>=\

А что ещё прикажешь бедному sendfile() делать, когда с той стороны сокет
закрылся?

>В FTPD.C есть такая штука упомянутом выше while
>if (err == -1){
>if (!cnt)
>goto oldway;
>goto data_err;
>}

Это здесь ни при чём. Посылатель (клиент) работает корректно.

>Вот. Может кто знает как тут можно выкрутится. Уж очень не хочется сдаваться и
>читать на стороне клиенте файл в массив а потом слать send()ом.

Дык, заверни на сервере read(2) в цикл и читай до тех пор, пока не вернёт 0 
либо ошибку.

Вал. Дав.

--- ifmail v.2.15dev5.3
 * Origin: Demos online service (2:5020/400)
SEEN-BY: 50/12 400/814 450/159 1024 461/43 132 640 469/999 4616/3 4625/8
SEEN-BY: 4641/444 5000/76 5000 5006/1 5007/1 5010/70 5011/13 5012/46 5015/28
SEEN-BY: 5019/31 5020/18 175 194 400 545 982 1057 1909 1922 2238 2395 2871
SEEN-BY: 5020/4441 5021/29 5025/3 5026/14 45 5027/12 5030/1080 1957 5034/10 13
SEEN-BY: 5035/3 38 5036/1 5045/7 5049/1 5051/15 5054/1 4 8 9 11 28 35 36 37 45
SEEN-BY: 5054/63 66 67 70 75 84 85 5059/9 5060/88 5061/15 5062/10 5063/3
SEEN-BY: 5064/7 5066/18 5075/5 5076/1 5077/70 5080/1003 5084/9 5085/13 5095/20
SEEN-BY: 5096/18 6001/10
PATH: 5020/400 545 5054/1 37