2011-01-31 17 views
5

Próbuję wymyślić najlepszy sposób na przesłanie pliku wideo przez gniazdo TCP. Zrobiłem standardowy program gniazda, ale po poleceniu read nie jestem pewien, w jaki sposób mogę go zapisać.Najlepszy sposób na przesyłanie wideo przez gniazdo TCP w C

przykładowy kod

//bind server socketfd 
if (bind(sfdServer, (struct sockaddr*)&adrServer, ServerAddrLen) < 0) 
    error("ERROR binding"); 
listen(sfdServer, 5); 
while(1){ 
    printf("Waiting for connections...\n"); 
    sfdClient = accept(sfdServer, (struct sockaddr*)&adrClient, &ClientAddrLen); 
    if(sfdClient < 0) 
     error("ERROR accepting"); 

    printf("Connection Established.\n"); 
    //set buffer to zero   
    bzero(buff, 2048); 
    printf("Reading from client.\n"); 
    numChar = read(sfdClient, buff, 2048); 

    //What should go here? 

    close(sfdClient); 
    close(sfdServer); 

} 

Chciałbym po prostu zapisać bufor w postaci pliku movie.mp4 czy coś takiego? Rozumiem, że muszę zmienić rozmiar bufora lub ewentualnie wysłać go w porcjach. Ale nie mogę znaleźć żadnych dobrych informacji na najlepszy sposób, aby to zrobić. Każda pomoc lub punkt we właściwym kierunku zostanie doceniony!

Odpowiedz

3

Napiszesz porcje bufora do pliku.

Najpierw otwórz plik wyjściowy do zapisu:

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 


    int outfd; 
    outfd = open("movie.mp4", O_WRONLY|); 

Następnie, po read(), napisz bajtów:

numWrite = write(outfd, buff, numChar); 

Należy pamiętać, że trzeba będzie radzić sobie z wieloma wyrwy/bufory, takie jak:

  • Albo read() lub write() powracający zero lub -1 (błąd)
  • Czytanie do momentu, gdy nie będzie dostępnych więcej bajtów. Teraz twój kod odczytuje tylko 2048 bajtów, a następnie zamyka gniazdo.
  • write() pisanie mniej niż wymagane bajtów (może się to zdarzyć na sieciowych systemów plików)
+0

Dobrze, używając tej informacji, udało mi się wszystko uporządkować. W tej chwili mogę przesyłać tekst z klienta java do tego serwera C. Ale jak już masz, zakładam, że tak długo, jak poprawnie zrzutu buforu, gdy otrzymam dane od klienta, powinien przenieść plik wideo w ten sam sposób? –

+1

Jeśli dobrze rozumiem twoje pytanie, tak: dla każdego bufora (np. 2048 lub mniej bajtów), który otrzymasz, jeśli zapiszesz go w swoim pliku, dopóki nie otrzymasz więcej bajtów, wszystko powinno działać. Połączenie sieciowe i gniazdo nie dbają o to, czy jest to tekst czy plik binarny. – payne

2

Po pierwsze, należy rozważyć użycie sendfile() lub ekwiwalent dla systemu. Oznacza to, że zamiast odczytywać fragment pliku w pamięci tylko po to, aby go gdzieś zapisać, powinieneś mapować swój deskryptor pliku i wysyłać wszystko za jednym razem.

Jeśli chodzi o chunking, TCP dba o podział strumienia na pakiety. Idealnie zdalny węzeł powinien dokładnie wiedzieć, ile można oczekiwać z góry, aby mógł obsłużyć wstępnie dojrzałe zakończenie (dlatego nagłówki HTTP zawierają długość treści).

Więc użyj jakiegoś uścisku dłoni przed wysłaniem danych. Następnie nadawca powinien po prostu wywołać sendfile() w pętli, zwracając uwagę na ilość wysłanych danych i zwróconą offet. Odbiornik powinien wywołać recv() w pętli, aby upewnić się, że wszystko dotarło (nie ma standardu "recvfile()").

+0

+1, Zgadzam się, sendfile() został stworzony, aby uprościć ten ból głowy i powinien być użyty, jeśli jest dostępny, podobnie jak wybór poll() nad select(). Niestety nie wszystkie platformy mają je. –

+0

Doceniam dane wejściowe, niestety aplikacja kliencka będzie w Javie, ponieważ pochodzi z urządzenia z systemem Android. Tak więc sendfile nie jest możliwe. –

Powiązane problemy