Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » socket recv Problem

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 <
000
01.07.2005, 15:22 Uhr
~KINK_LEO
Gast


Hi Leute
Ich habe da einen kleinen Server und Client geschrieben und bin da auf ein Problem gestossen ......
So im grunde läuft alles zu meiner Zufriedenheit aber ein Problem plagt mich schon mehr als ein 1/2 Jahr das ich dann umgangen habe...
Unzwar Kommunitieren die beiden immer abwechselnd Client stell eine Anfrage Server nimmt diese an.

Das PROBLEM :
wenn der Server 2 mal Sendet also :
send ( sock,"Beginne Verarbeitung ...",strlen("Beginne Verarbeitung ..."),0);
.
.
. ( VERARBEITUNG )
.
int senddata = send ( sock,erbgebnis-structur,sizeof(erbgebnis-structur),0);

dann ist der Return wert vom senden ok aber der Client empfangt nur einen bruchteil.
Das Komische immer den Selben bruchteil um genau zusein der Server sendet 672 Bytes der Client empfangt 512 immer !

Wenn ich das ganze dann so ändere :

send ( sock,"Beginne Verarbeitung ...",strlen("Beginne Verarbeitung ..."),0);
.
.
. ( VERARBEITUNG )
.
int recv( sock,buffer,10,0); // Client sendet "OK"
int senddata = send ( sock,erbgebnis-structur,sizeof(erbgebnis-structur),0);

Dann funzt das :-?

Die erste überlegung ist natürlich das flushen der Buffers ( fflush(NULL ) ) bringt aber nichts...

Dann habe ich mir eine recv_packed funktion geschrieben warted mit select und empfängt Bytesweise timeout 30 sec biringt genauso wenig .

Bin eigentlich ganz fitt in socketprogrammierung also ein DAU Fehler ist ausgeschlossen ....

Bin für jede anregung Dankbar also bis denne .... LEO
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.07.2005, 16:25 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hi, wahrscheinlich ist der recv-buffer nur 512 bytes groß, wodurch alles was danach ankommt nicht mehr ankommt. mit setsockopt kann man das größer einstellen. Ansonsten sollte deine überlegung funktionieren.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
01.07.2005, 16:28 Uhr
~KINK_LEO
Gast


Wenn das so wäre warum funktioniert das denn wenn ich vorher nach mal etwas sende ???
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
01.07.2005, 17:28 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von ~KINK_LEO:
?
Die erste überlegung ist natürlich das flushen der Buffers ( fflush(NULL ) ) bringt aber nichts...



Nö, weil fflush aus der StdIO kommt und folglich nur auf Streams angewendet werden kann, die ein FILE darstellen, ein Socket hingegen ist eine vom System verwaltete resource, die auch einen Buffer im Stdio Sinne hat.

Ich denke mal, daß Du das, was ducmit "sock" bezeichnest Dir durch einen accept besorgst und dann eben die Verarbeitung machst und dann sock schliesst. Die spannende Frage ist dann, wie du das socket schließt: möglicherweise schliesst Du es zu früh, bevor der Client den kompletten Request empfangen hat, aber es ist ebenso denkbar, daß Du close anstelle von shutdown verwendet hast.


Zitat von ~KINK_LEO:
?
Bin eigentlich ganz fitt in socketprogrammierung also ein DAU Fehler ist ausgeschlossen ....


Das eine hat aber nichts mit dem anderen zu tun. Jeder macht DAU Fehler.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
02.07.2005, 00:25 Uhr
CDW



hm, recv muss ja nciht alles auf einmal empfangen... zumindest kenne ich das von Windowssockets:

Zitat:

For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much information as is currently available—up to the size of the buffer supplied. If


hier ist eigentlich das woran ich mich halte (mit beispielcode):
es ist zwar C++ kann aber problemlos konvertiert werden

C++:
while(true)
{
    int retval;
    retval = recv(hSocket, tempBuffer, sizeof(tempBuffer)-1, 0);
    if (retval==0)
    {
        break; // Connection has been closed
    }
    else if (retval==SOCKET_ERROR)
    {
        throw HRException("socket error while receiving.");
    }
    else
    {
        // retval is number of bytes read
        // Terminate buffer with zero and print as string
        tempBuffer[retval] = 0;
        cout << tempBuffer;
    }
}


Quelle:
http://madwizard.org/view.php?page=tutorials.networking.chapter6&lang=cpp
also es geht im Prinzip darum, dass man bei recv eben alles mitzählt - bis die Daten wirklic auch alle empfangen wurden. Im Prinzip:

C++:
rueckgabe=0;
empfangen=0;
repeat
   rueckgabe=recv(hsocket,bufferpositionszeiger,sizeof(buffer)-empfangen);
   empfangen=empfangen+rueckgabe;
   bufferpostionszeiger=bufferpostionszeiger+empfangen;
   if (epmfangen==sizeof(buffer) tue irgendwas weil der Buffer voll ist;
while (rueckgabe!=0)||(rueckgabe!=SOCKET_ERROR);


ich weiß zwar nicht ob man die Zeiger in C so addieren kann, aber ich hoffe dass es vom Prinzip her verständlich rüberkam.
--
EB FE

Dieser Post wurde am 02.07.2005 um 00:26 Uhr von CDW editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
02.07.2005, 09:13 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Am sinnvollsten wäre folgendes: zuerst sendest du 4 Bytes (nämlich Länge der nachfolgenden Daten) das soll der Client bestätigen. anschliessend sendest du immer Pakete, nicht zu groß, aber nicht zu klein. Und jedes soll der Client bestätigen. Sobald beim Client eben Länge-Bytes erreicht sind soll er am Client verarbeiten
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
02.07.2005, 12:19 Uhr
(un)wissender
Niveauwart


Das tut nicht not, da das schon von der tcp-Schicht erledigt wird. Die Schleife ist gut. Ev. mit einem Sleep(0) dazwischen.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.07.2005, 10:23 Uhr
~KINK_LEO
Gast


Hi Leute
Danke für die zahlreichen Tips .....
Ich versuche es mal mit shut_down ..... die anderen Tips habe ich schon ausprobiert ich habe in den Protokollen bereits ein Prefix von 2 Bytes ( länger der über TCP/IP verschieckten Struktur ) nur wie beschrieben funzt es in diesem einem beispiel net ....
Ich gib noch bescheid ob es mit shut doen fuktioniert
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.07.2005, 15:12 Uhr
~KINK_LEO
Gast


Ich habs versucht mit shut_down NEGATIVE leider ...
Dann hab ich noch mit SOL_LINGER option ( setsockopt) versucht auch negative daraus schliesse ich das auch nicht da ist was noch gesendet werden muss ....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.07.2005, 15:45 Uhr
~Konrad
Gast


mach was CDW gesagt hat. du holst nicht alles aus dem netbuffer ab. oder du prüfst den rückgabewert von send() nicht und der server sendet nicht alle daten.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


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: