[WinSock] transfer plików

Odpowiedz Nowy wątek
2007-10-09 18:43

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

Piszę sobię prosty programik do przesyłania plików. Na początek chciałem przesłać 1 "na sztywno" zadeklarowany plik *.jpg.

Serwer mam działający dobrze, sprawdzałem różnymi aplikacjami i działa. Odbiera dane i rozsyła do wszystkich połączonych klientów.

I na początku chciałem spróbować z 2 klientami:

Wysyłanie:

#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <fstream.h>
#include <conio.h>

using namespace std;

int main()
{
    WSAData wsa;
    SOCKET s1;
    struct sockaddr_in addr1;
      char bufor[999999];

    int addrlen;

fstream plik;
    char *dane;
    int dlugosc;

  plik.open("obraz.jpg",ios::in|ios::binary);
  plik.seekg(0,ios::end);
  dlugosc=plik.tellg();
  dane=new char[dlugosc];
  plik.seekg(0,ios::beg);
  plik.read(dane,dlugosc);
  plik.close();
  cout<<"Wczytalem plik"<<endl;

    if(WSAStartup(MAKEWORD(2,0),&wsa)==SOCKET_ERROR)
    {
        cout<<WSAGetLastError()<<endl;
        WSACleanup();
    }
    else
    {
        cout<<"WSA ready."<<endl;
    }

     s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    struct hostent *host;
    host=gethostbyname("127.0.0.1");
    memset( &addr1, 0, sizeof addr1 );
    addr1.sin_family = AF_INET;
    addr1.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
    addr1.sin_port = htons(1337);
    if(connect(s1,(struct sockaddr *) &addr1, sizeof(addr1))==SOCKET_ERROR)
    {
        cout<<WSAGetLastError()<<endl;
        WSACleanup();
    }
    else
    {
        cout<<"Connected"<<endl;
    }
    cout<<"wcisnij cos!"<<endl;
    getch();
    itoa(dlugosc,bufor,10);
    send(s1,bufor,sizeof(bufor)+1,0);
    send(s1,dane,dlugosc,0);
    cout<<"Wyslalem plik"<<endl;

system("PAUSE");
return 0;
}

A Dobieranie tak:

#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <fstream.h>
#include <cstdlib>

using namespace std;

int main()
{
    WSAData wsa;
    SOCKET s1;
    struct sockaddr_in addr1;

      char *bufor;

fstream plik2;
plik2.open("plik.jpg",ios::out|ios::binary);
    int dlugosc;

    if(WSAStartup(MAKEWORD(2,0),&wsa)==SOCKET_ERROR)
    {
        cout<<WSAGetLastError()<<endl;
        WSACleanup();
    }
    else
    {
        cout<<"WSA ready."<<endl;
    }

     s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    struct hostent *host;
    host=gethostbyname("127.0.0.1");
    memset( &addr1, 0, sizeof addr1 );
    addr1.sin_family = AF_INET;
    addr1.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
    addr1.sin_port = htons(1337);
    if(connect(s1,(struct sockaddr *) &addr1, sizeof(addr1))==SOCKET_ERROR)
    {
        cout<<WSAGetLastError()<<endl;
        WSACleanup();
    }
    else
    {
        cout<<"Connected"<<endl;
    }

    recv(s1,buf,sizeof(buf)+1,0);
    dlugosc=atoi(buf);

bufor=new char[dlugosc];
        recv(s1,bufor,dlugosc,0);

plik2.write(bufor,dlugosc);
plik2.close();

    cout<<"Zapisalem obraz"<<endl;

system("PAUSE");
return 0;
}

Problem w tym, że nie za bardzo mi to działa. Łącze się z serwerem, wielkość pliku wysyła się niby poprawnie, ale sam plik coś nie chce...
Wie ktoś gdzie leży błąd?

Wybaczcie tragiczny kod i brak wcięć :-/

Pozostało 580 znaków

2007-10-09 19:33

Rejestracja: 15 lat temu

Ostatnio: 8 lat temu

0

poczytaj dokladnie o recv
http://msdn2.microsoft.com/en-us/library/ms740121.aspx

niekoniecznie musi zwrocic tyle ile jest w bufor (czytal bym do chwili odebrania odpowiedniej ilosci bajtow) - patrz co zwraca recv


Pozostało 580 znaków

2007-10-09 20:09

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

Hmm... fakt, masz rację. No i trochę to poprawiłem, teraz odbiera chyba plik do końca, bo odebrany plik zajmuje tyle co wysłany, ale nic w nim nie ma, tzn nie ma obrazu. Podejrzewam, że coś nie tak z zapisem jest...

int odebrano;

...

       do
        {
        odebrano=recv(s1,bufor,dlugosc,0);
    } while( odebrano > 0 );
    plik2.write(bufor,dlugosc);
     plik2.close();

    cout<<"Zapisalem obraz"<<endl;

Mniej więcej tak to wygląda...

Edit//

Co jeszcze dziwniejsze, otworzyłem plik odebrany notatnikiem i plik wysłany i są od siebie inne... Nie mam pojęcia dlaczego. Czyżby nie wszystko się wysłało? Jak bez wysyłania otworzę w ten sposób plik i zapiszę to wszystko jest OK. Nie wiem już co myśleć :/

Edit2//

Zamiast obrazka wysłałem plik tekstowy:

oto testowy przesyl

W otrzymanym pliku mam:

rzesyloto testowy p

Wyraźnie widać, że się pakiety coś mieszają... Jak temu zapobiec?

Pozostało 580 znaków

2007-10-09 21:44

Rejestracja: 15 lat temu

Ostatnio: 8 lat temu

0
do
        {
        odebrano=recv(s1,bufor,dlugosc,0);
    } while( odebrano > 0 );
    plik2.write(bufor,dlugosc);

pomysl..... nie dokonca to jeszcze

do
        {
        odebrano=recv(s1,bufor,dlugosc,0);
    plik2.write(bufor,odebrano);
    } while( odebrano > 0 );

dalej mozna (nie sprawdzam mniej wiecej idea) .. plik moze miec zero bajtow :)

        odebrano=recv(s1,bufor,dlugosc,0);
       while( odebrano > 0 ) {
    plik2.write(bufor,odebrano);
        odebrano=recv(s1,bufor,dlugosc,0);
    } 

Pozostało 580 znaków

2007-10-09 21:52

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

Hmm nie do końca rozumiem to co napisałeś, jednak spróbowałem tak:

odebrano=recv(s1,bufor,dlugosc,0);
       while( odebrano > 0 )
        {
    plik2.write(bufor,odebrano);
        odebrano=recv(s1,bufor,dlugosc,0);
    }

Nie wiem czy o takie rozwiązanie Ci chodziło, jednak to jest całkiem nie tak, bo nie dość, że plik odebrany jest jakieś 900razy większy to i pusty :P

Edit//
W sumie to nie pusty bo na samym dole jest cała masa jakiegoś śmiecia, ale na końcu jest poprawny tekst, który przesyłam. Teraz tylko, skąd się te śmieci biorą...

Pozostało 580 znaków

2007-10-10 11:10

Rejestracja: 15 lat temu

Ostatnio: 8 lat temu

0

idea jest taka:

1) masz bufor

2) odbierasz do niego dane (sa zapisane od poczatku bufora do odebrane)
3) zapisujesz bufor do pliku
4) ofset pliku sie przesuwa (to automat - na konec )
5) wracamy do pkt 2


Pozostało 580 znaków

2007-10-10 14:57

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

No OK, już rozumiem i wydaje mi się, że to dobra idea i powinno działać jak ta lala, a jednak nie... Skąd się biorą te "syfy" w pliku?

Pozostało 580 znaków

2007-10-10 15:33

Rejestracja: 15 lat temu

Ostatnio: 8 lat temu

0

chech slepota ze mnie .... popatrzylem tylko na recv a gdzie w serwerze bind i listen ?

popatrz (podstawy), twoj serwer nie nasluchuje ...
http://www.codeproject.com/internet/winsockintro01.asp


Pozostało 580 znaków

2007-10-10 15:56

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

Nie nie, żadna z tych aplikacji, których kody tutaj są nie jest serwerem!
Serwer mam oddzielny, napisałem sobie go tak porządniej i testuje na nim wszystko inne. I o ile serwer napisać potrafię to z klientem mam problem. Tutaj w tym przypadku rozdzieliłem klienta na dwie części żeby łatwiej było na początku. Jeden z tych klientów wysyła, a drugi odbiera.

Offtop//
Zna ktoś może jakąś książkę o programowaniu sieciowym w Windows?

Pozostało 580 znaków

2007-10-10 18:15

Rejestracja: 15 lat temu

Ostatnio: 8 lat temu

0

dobre na poczatek

PISANIE PROGRAMOW INTERNETOWYCH
SOPALA A.
http://www.mareno.pl/prod/MIDN/83-7279-003-5

ps. moze jednak cos w serwerze nie tak ??? skoro dobiera wiecej niz potrzeba ....


Pozostało 580 znaków

2007-10-10 19:09

Rejestracja: 12 lat temu

Ostatnio: 12 lat temu

0

Nie no serwer zdaje się być OK. Hm spróbuję jeszcze raz to wszystko przepisać, na nowo i dokładniej, może coś poprawię w międzyczasie.
Tymczasem dziękuję za pomoc! :)

P.S. Ta książka chyba jest o Javie, a mi chodzi o C++, przepraszam, że nie sprecyzowałem.

Pozostało 580 znaków

Odpowiedz

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