Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Receive bei Socketverbindung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
08.02.2007, 20:31 Uhr
~bellacarte
Gast


Hallo, ich hab mir eine Socketklasse geschrieben die u.a. auch eine funktion hat zum empfangen von daten.

die daten schicke ich mir von einem seperaten clientprogramm zu meine server. es handelt sich dabei um eine tcp/ip server. ich hab allerdings beim empfangen des datenstroms ein seltsames problem. Beim Empfangen verhält sich mein programm irgendwie "nicht den erwartungen entsprechend".

Ich schicke mir zum Test eine datei die 2000 Byte groß ist, wenn ich mit dem Debugger drauf gehe erhalte ich etwa ~1400 Byte und plötzlich springt der Debugger aus der Routine raus ins Nirvana.

Irgendwas scheitn da einen abbruch auszulösen. Der Debugger macht aber nirgendenwo weiter. Das programm befindet sich noch im debugmodus, aber nichts passiert mehr.

Er verlässt die schleife mittendrin, wenn etwa 2/3 aller byte gelesen wurden(sind in meinem testfall derzeit immer ~2000). Laut Debugger ereicht mein Programm nie die Return anweisung, kompilieren lässt sich aber alles fehlerfrei.

Die Datei dich mir sende lese ich mir mit fstream ein und schicke diese dann los, könnte es evtl. daran liegen das irgendwann ein zeichen kommt(z.b. carriege return) das den debugger so aus der bahn haut?

Hier mal meine Receiv-Funktion

C++:
std::string CCreateSocket::ReceivData(SOCKET recvSocket)
{
    int iLenReceived = 0;
    std::string    tempString;

    while(iLenReceived +=recv(recvSocket, this->buf, 256, 0))
    {
        std::cout<<WSAGetLastError();
        tempString = tempString + std::string(this->buf);
        /* Wegen dem Empfangen gucken, läuft im Loop, ohne Ende */
    }

    return tempString;  
}
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.02.2007, 20:52 Uhr
-Biohazard-



Ich mache das immer auf folgende Art:
1. Ich lese die Datei binär
2. Ich verschicke die Datei in 256Bytes-Packeten und addiere die 256 immer zu einer Variablen
Zudem achte währenddessen darauf, dass der gelesene Teil der Datei (Bsp: 9000Bytes) immer kleiner als die Dateigröße - die Lesegröße (also beispielsweise 9253 Bytes (Filesize) - 256Bytes < 9000 Bytes!) ist
Ansonsten musst du die "Lesegröße" umändern
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.02.2007, 21:04 Uhr
~bellacarte
Gast



Zitat von -Biohazard-:
Ich mache das immer auf folgende Art:
1. Ich lese die Datei binär
2. Ich verschicke die Datei in 256Bytes-Packeten und addiere die 256 immer zu einer Variablen
Zudem achte währenddessen darauf, dass der gelesene Teil der Datei (Bsp: 9000Bytes) immer kleiner als die Dateigröße - die Lesegröße (also beispielsweise 9253 Bytes (Filesize) - 256Bytes < 9000 Bytes!) ist
Ansonsten musst du die "Lesegröße" umändern


woher weis ich den wie groß die datei ist, die ich empfange?! die information habe ich doch erst wenn die datei fertig empfangen ist?!?

das senden klappt gut, wobei ich es derzeit nicht abfange wenn ich weniger information hab, als der buffer groß ist. ich schicke immer 256byte bis eof() true liefert.

das problem liegt aber beim receiv. wie erfahre ich die größe der datei die ich empfange?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.02.2007, 22:49 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,
damit du weißt wie groß die datei ist, solltest du die größe zuerst übertragen, dann immer "häppchen" versenden und einlesen, wie biohazard schon geschrieben. Wichtig ist jedoch immer eine Fehlerabfrage - damit dir dein Programm nicht hängen bleibt nur weil irgendwo die verbindung spinnt. Die Häppchen können schon größer sein, du kannst die größe des Sendepuffers ja abfragen (getsockopt), mehr als in den Sendepuffer reinpasst sollte man natürlich nicht auf einmal senden, und man muss die rückgabe vom send genaustens prüfen, denn da drin steht wieviel versand (also in den sendepuffer übertragen) wurde.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.02.2007, 22:40 Uhr
~bellacarte
Gast



Zitat von FloSoft:
Hi,
damit du weißt wie groß die datei ist, solltest du die größe zuerst übertragen, dann immer "häppchen" versenden und einlesen, wie biohazard schon geschrieben. Wichtig ist jedoch immer eine Fehlerabfrage - damit dir dein Programm nicht hängen bleibt nur weil irgendwo die verbindung spinnt. Die Häppchen können schon größer sein, du kannst die größe des Sendepuffers ja abfragen (getsockopt), mehr als in den Sendepuffer reinpasst sollte man natürlich nicht auf einmal senden, und man muss die rückgabe vom send genaustens prüfen, denn da drin steht wieviel versand (also in den sendepuffer übertragen) wurde.


ich hab ein kleiens problem damit, das ich mit send() nur char* daten schicken kann.(sizeoffile ist ein unsigned long)

die größe der datei schicke ich vor den eigentlichen daten vorraus:

C++:
            send(sendSocket,(char*) sizeOfFile, sizeof(unsigned long), 0);



die will ich dann wie folgt in der receive routine annehmen:

C++:
char sizeBuffer[10];
recv(recvSocket, sizeBuffer, sizeof(unsigned long), 0);
unsigend long sizeOfFileToReceive = (int) sizeBuffer;



wenn ich sizeBuffer dann wieder zurück caste bleibt irgendwie nichts übrig. der wert in meinem unsigend long ist = 0;

was mach ich falsch?

Dieser Post wurde am 10.02.2007 um 10:28 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.02.2007, 00:26 Uhr
Blubber2063



Da machst du auch was falsch, du kastest ein char Feld nach int, du musst aber nach int* casten und das ganze dereferenzieren. Achja und du solltest schon nach long casten wenn dein typ long ist, auch wenn das meist auf x86 32bit long = int ist, dass muss nicht so sein.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
10.02.2007, 10:31 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


ok also:



C++:
// hier den & nicht vergessen!
char *mysize = (char*)&sizeOfFile;

send(sendSocket, mysize, sizeof(unsigned long), 0);





C++:
char *mysize = (char*)&sizeOfFileToReceive;

recv(recvSocket, mysize, sizeof(unsigned long), 0);



Ansonstne ist int nicht umbedingt gleich unsigned long!
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
10.02.2007, 21:36 Uhr
~bellacarte
Gast



Zitat von FloSoft:
ok also:



C++:
// hier den & nicht vergessen!
char *mysize = (char*)&sizeOfFile;

send(sendSocket, mysize, sizeof(unsigned long), 0);





C++:
char *mysize = (char*)&sizeOfFileToReceive;

recv(recvSocket, mysize, sizeof(unsigned long), 0);



Ansonstne ist int nicht umbedingt gleich unsigned long!


müsste das zweite nicht anders lauten? da müsste ich doch erst empfangen(die größe der datei) und dann die information in mysize in ein usigned long casten.

hab das jetzt mal so umgesetzt, wie es nach meinem verständis in etwa aussehen sollte
auszug aus meiner derz. receive methode:

C++:
char*            buffer = NULL;
recv(recvSocket, buffer, sizeof(unsigned long), 0);
    
sizeOfFileToReceive = (unsigned long) &buffer;



aber die zahl die dabei entsteht ist viel zu groß, irgendwas im 100.000er bereich. zudem wirft der compiler eine warnung aus
Zitat:

'type cast' : pointer truncation from 'char **__w64 ' to 'unsigned long'

*help*
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
11.02.2007, 04:22 Uhr
Blubber2063



1. hinter deiner Buffer Variable sollte Speicher liegen, also der Zeiger sollte nicht ins Nirvana zeigen.
2. Wenn Buffer ein Feld ist, dann gibts du nicht &buffer sondern buffer an(Felder werden in C/C++ durch Zeiger auf das erste Element repräsentiert.
3.Flosoft hats es dir schon vorgemacht, aber natürlich vorrausgesetzt das du erkennst, das sizeOfFileToRecive eine Variable vom Typ unsigned long ist.

Dieser Post wurde am 11.02.2007 um 04:23 Uhr von Blubber2063 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.02.2007, 09:37 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Wenn dir meines nicht gefällt, dann benutz das hier:


C++:
char buffer[sizeof(unsigned long)];
recv(recvSocket, buffer, sizeof(unsigned long), 0);
    
sizeOfFileToReceive = *(unsigned long*)&buffer;



Auch wenn das nur ein nochmaliges Umkopieren bedeutet, meine Lösung hat eben diesen Schritt weniger.
--
class God : public ChuckNorris { };

Dieser Post wurde am 11.02.2007 um 09:39 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: