Odebranie pliku przez socket

0

Witam,
chce napisać server w c/c++ który odbierze od klienta plik w określonym formacie (np. .txt) i zapisze go na określoną ścieżkę - krótko mówiąc metodę recv().
Klienta już mam, działa on poprawnie w innym języku (sprawdzałem czy dojdzie w tym samym języku).
Połączenie jest nawiązane, zwykły text może dojść(chat) - czyta mi wnętrze pliku i go wyświetlić na konsoli.
Domyślam się że buffor musze jakoś zamienić na plik - ktoś podpowie?

1

Zamiast wypisywać do konsoli zapisz do pliku, w czym problem? Wystarczy zamienić std::cout na obiekt std::ofstream albo printf na fprintf...

1

potrzebne ci boost asio / boost beast
https://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp11_examples.html
https://www.boost.org/doc/libs/1_66_0/libs/beast/doc/html/beast/examples.html

Więcej się nie da napisać, bo sypnąłeś ogólnikami, więc zakładam, że potrzebny ci serwer HTTP.

1

https://github.com/ipkn/crow/issues/224

Edit: ten link dotyczy protokołu HTTP, nie zauważyłem słowa "socket".
Na pewno chcesz to robić na tak niskim poziomie?

0

Dziękuje za odpowiedzi.
Jestem zielony w c/c++, więc każda podpowiedź na wagę złota.
**ofstream ** plik .txt zapisuje się z błędami, a taki .png już nie do odczytu.
Nie chcę tego robić niskopoziomowo, ale muszę to zrobić - takie wymagania projektu. Nie mogę niestety użyć boost asio / boost beast.
Jest to server TCP.

1

Pokaż w takim razie kod odpowiedzialny za odczyt.
(pseudokod pisany z pamięci)

ofstream out("blah", std::ios::bin);
//...
while(socket.ready_read()) {
    auto read = socket.read(buf, 1024);
    out.write(buf, read);
}

Zakładam, że chcesz coś podobnego.

0
        int bytesReceived = recv(clientSocket, buf, 4096, 0);
        outfile.write (buf,4096);```
1

W TCP dane są traktowane jak strumień, nie możesz na pałę założyć ile danych otrzymałeś z recv - nie ignoruj bytesReceived

0

domyślam się że muszę zapętlić, jeśli mój określony bufor się zapełni . Kiedy nie będzie miał co już przyjmować to wychodzi z pętli i w jakiś sposób go zapisać wyściowo.
Dobrze rozumiem?

3

Musisz zrozumieć, że jeśli ktoś ci wysłał 1832 bajty, to nawet jeśli będziesz próbował odczytać 4000 bajtów to nie masz gwarancji, że pierwszy odczyt da ci 1832.
Podczas odczytu może dostać dowolną ilość danych od 1 bajta do 1832 (bo nadawca więcej nie wysłał). Wynika to z tego, że każdy pośrednik (element sieci na drodze strumienia), może ci podzielić strumień danych na kawałki dowolnej długości, albo ci może je posklejać.
Dlatego nie wolno ci ignorować wartości zwracanej przez socket.read(buf, 1024);, a całość wiadomości musisz posklejać sam, albo przetwarzać każdy kawałek na bieżąco.

0

Dzieki wszystkim za pomoc i nakierowanie do rozwiazania problemu - pliki przechodzą w różnych formatach .png, .pdf, z .txt mam problem odczytu ale jest on chyba zwiazany z kodowaniem zapisu(UTF).
Dwie najwazniejsze linikii kodu to:

while(int bytesReceived = recv(clientSocket, buf, 4096, 0))
oraz
bytes_written=fwrite(buf,sizeof(char),bytesReceived, fr);

1 użytkowników online, w tym zalogowanych: 0, gości: 1