🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.os.linux.programowanie
Article #72456

zapis strumieni multicastowych do pliku a utrata pakietów

#72456
From: Arek
Date: Wed, 09 May 2012 12:19
85 lines
3685 bytes
Witam

Borykam się z małym problem dot. zapisu odebranego po IP strumienia 
danych (strumień multicastowy) do pliku - wygląda na to, że system się 
nie wyrabia i gubi odbierane ramki z interfejsu eth0 w czasie zapisu na 
dysk - program ich nie otrzymuje. Strumień wejściowy od 10Mbps do 
40Mbps, ale ten parametr nie gra roli, bo i przy 10Mbps się nie wyrabia 
system.

Otwieram socket w trybie nieblokującym, funkcja poll sprawdzam czy są 
dane do odczytu (flaga POLLIN), następnie ręcznie filtruję wybrane ramki 
i zapisuję je do pliku. Próbowałem buforować zapisywane dane i zapisywać 
je w większej ilości (bufor w programie na 10000 ramek po 188bajtów przy 
jednym wywołaniu write - pomaga ale nie do końca - gubi mniej, ale dalej 
gubi), zapisywać w trybie nie blokującym, czytać z socketa w trybie 
blokującym, ale co bym nie robił to i tak co jakiś czas system gubi 
ramki przychodzące na interfejs eth0. W przypadku gdy nie zapisuje 
odebranych ramek tylko je analizuje wszystko jest ok - system nie gubi 
ramek i dostarcza je wszystkie do mojego programu. Próbowałem na różnych 
maszynach (systemy 32/64bit), ale nic mi to nie pomogło.

Proces programu to 4% zajętości procesora podczas zapisu i 2% bez zapisu 
na wiekowej już maszynie na której to go testuję. Zauważyłem, że vmstat 
w chwili gdy występują utraty pakietów zgłasza bo (Blocks sent to a 
block device (blocks/s)) na poziomie 30.000 (normalnie 0) i wa (Time 
spent waiting for IO) na poziomie 30 (normalnie 0). Wydaje mi się, że te 
30.000 bloków/s będzie tu kluczem - może zmusić system by częściej 
zapisywał, ale mniejszą ilość (jakiś flush po write)? Czy może coś w 
programie można usprawnić?

pozdrawiam
Arek


Poniżej najważniejsze fragmenty programu:

bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));

setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&imreq, 
sizeof(struct ip_mreq));

fcntl(sock, F_SETFL,O_NONBLOCK|FASYNC);

pfd[0].fd = sock;
pfd[0].events = POLLIN;

ts_fileptr=open(ts_filename,O_WRONLY|O_CREAT|O_TRUNC, 
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

if ((flags=fcntl(ts_fileptr, F_GETFL))==-1)
{
    perror("Error get flags for write");
    exit(0);
}

if (fcntl(ts_fileptr, F_SETFL, flags | O_NONBLOCK)<0)
{
    perror("Error set flags for write");
    exit(0);
}

do
{
if (poll(pfd,1,3000))
{
   if (pfd[0].revents & POLLIN)
   {


       recived = recvfrom(sock, buffer, MAXBUFSIZE, 0, (struct sockaddr 
*)&saddr, &socklen);

/*
tu funkcje analizujące, filtrujące, buforujące, itp...
*/

if (write(ts_fileptr,outbuff,chunksize)!=chunksize )
             {
               perror("Error in write");
               exit(0);

             }
     }
   }
} while (1);
Technical Details
Message-ID: <jodnc3$2rs$1@node2.news.atman.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!.POSTED!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!.POSTED!not-for-mail
From: Arek <arek@from.hell.pl>
Newsgroups: pl.comp.os.linux.programowanie
Subject: zapis strumieni multicastowych do pliku a utrata
 pakietów
Date: Wed, 09 May 2012 14:19:12 +0200
Organization: ATMAN - ATM S.A.
Lines: 85
Message-ID: <jodnc3$2rs$1@node2.news.atman.pl>
NNTP-Posting-Host: user-109-243-113-246.play-internet.pl
Mime-Version: 1.0
X-Trace: node2.news.atman.pl 1336565956 2940 109.243.113.246 (9 May 2012 12:19:16 GMT)
X-Complaints-To: usenet@atman.pl
NNTP-Posting-Date: Wed, 9 May 2012 12:19:16 +0000 (UTC)
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20120327 Thunderbird/11.0.1
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit