Winsock, przesyłanie plików

Odpowiedz Nowy wątek
2011-07-18 18:36
0

Witam, to znowu ja...

Chciałbym przesłać plik jpg używając własnego programu. Czytając różne fora i poradniki wyodrębniłem listę kroków:
(klient)

  1. Otwieram plik w trybie binarnym (std::ios::binary)
  2. Dzielę plik na części.
  3. Wysyłam każdą część.
    (serwer)
  4. Otrzymuję dane.
  5. Zapisuję do pliku binarnego.

Niestety, mimo że robię wszystkie kroki przesłany przeze mnie plik jpg utracił obraz (pisze: nieprawidłowy format), a plik exe stracił możliwość uruchamiania się. Wychodzi, że robię coś nie tak. Czy ktoś mógłby napisać coś w stylu krótkiego tutoriala? Wystarczy zwykły kod z komentarzami żebym mógł porównać go ze swoim rozwiązaniem.

Z góry dzięki za pomoc :)

Pozostało 580 znaków

2011-07-18 20:24
qwe
0

może wyślij cały plik nie dzieląc go na części ?

To wyjątkowo zły pomysł... Nie wyobrażam sobie przesłania tak pliku > 10 MB :P - Patryk27 2011-07-18 20:28
ajtam, ajtam, ... :p - Misiekd 2011-07-18 21:20
Tu nie chodzi nawet o to czy ktoś sobie wyobraża trzymać 10MB w pamięci, ale o to że recv() i send() przesyłają 100% danych jeśli nie ma ich więcej niż 1024B. Najwięcej ile udało mi się przesłać za jednym zamachem to 7kB z groszem. Także wg. mnie używając uniksowego interfejsu sieciowego po prostu nie da się przesłać za jednym zamachem plików większych niż skromne pliki txt. - several 2011-07-18 21:40

Pozostało 580 znaków

2011-07-18 20:51
0

Jak masz jakiś problem to zawsze podawaj kod, więc wklej go tu i zobaczymy co jest nie tak.


<error>There was an error during loading user signature. Please try to reboot the Universe and check again.</error>

Pozostało 580 znaków

2011-07-18 21:47
0

Ja tam sądzę, że nie ma żadnego błędu bo nie ma żadnego kodu. Na innym forum podpowiedzieli autorowi tematu algorytm ale i tak nie potrafi go zaimplementować. No ale mogę się mylić...

Pozostało 580 znaków

2011-07-19 07:56
0
several napisał(a)

Ja tam sądzę, że nie ma żadnego błędu bo nie ma żadnego kodu. Na innym forum podpowiedzieli autorowi tematu algorytm ale i tak nie potrafi go zaimplementować. No ale mogę się mylić...

No i mylisz się. Kod jest, ale szczerze mówiąc to się go wstydzę. Przesyłanie plików jest przez wszystkich tłumaczone jako oczywistość, a ja mam z tym problem, no ale proszę.

Kod do wysyłania (pomijam wszystkie łączenia z socketem, makroinstrukcje, itp. bo kod się kompiluje), pętla for była używana wcześniej (zamieniałem znak char na string który reprezentował jego bity, np. 00110011 i przesyłałem każdy znak pojedyńczo):

std::ifstream plik;
plik.open(FILE, std::ios::binary);
 
if (plik.is_open() == false)
{
    std::cout << "\n>> Opening file error!";
    _getch();
    return(1);
}
 
while (!plik.eof())
{
    std::string line;
    std::getline(plik, line);
 
    if (line.length() > 0)
    {
            for (unsigned i = 0; i < line.length(); i++)
        {
            bool bDone = false;
            while (!bDone)
            {
                int bytes = send(sock, &line[i], BUFOR, NULL);
                if (bytes > 0)
                {
                    std::cout << "\n>> Message (" << bytes << " bytes) sent!";
                    bDone = true;
                }
                else if (bytes < 0) std::cout << "\n>> Data sending error: " << WSAGetLastError();
                else 
                {
                            std::cout << "\n>> Connection lost!";
                            bDone = true;
                }
            }//end: while
        }//end: for
    }//end: if
}//end: while (eof)
plik.close();           

Kod odbierania (po stronie serwera):

char msg[BUFOR];
std::string txt;                
bool bDone = false;
while (!bDone)
{
    int bytes = recv(client, msg, BUFOR, NULL); 
    if (bytes > 0) 
    {
        std::cout << msg;
        txt += msg;
    }
    else if (bytes < 0) std::cout << "\n>> Error: " << WSAGetLastError();
    else 
    {
            std::cout << "\n>> User disconnected!";
                bDone = true;
    }
}
 
std::ofstream plik(FILE, std::ios::ate | std::ios::binary);
if (plik.is_open() == true)
{
    plik << txt;
    plik.close();
}
else std::cout << "\n>> Opening file error!";

EDIT:
Aj, aj... Już nieważne, działa. Przeczytałem tutorial na stronie www.cpp0x.pl i dowiedziałem się, że traktowanie pliku, nawet otwartego w trybie binarnym, jako strumień powoduje odczytanie i zapis jako tekst... Użyłem write() i read() i jest ok...

edytowany 2x, ostatnio: robin3d, 2011-07-19 08:59
Jeszcze taka mała rzecz, nie powinno być else if (bytes &lt;= 0) w kliencie (line 26), bo jak nic nie przejdzie to będzie zero, a nie mniej? - xeo545x39 2011-07-19 15:44

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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