2016-09-29 6 views
-1

Dies ist eher eine Anfrage zur Bestätigung als eine Frage, so werde ich es kurz halten. (Ich bin von meinem PC weg und kann diese Lösung nicht einfach zum Test implementieren).C++ Socket Buffer Größe

Ich schreibe ein Programm, um eine Bilddatei von einer HimbeerPi an meinen PC zu senden, die per Webcam (zusammen mit Metadaten) aufgenommen wurde.

Ich habe herausgefunden, dass das Bild etwa 130kb ist, der Paketkopf ist 12b und die zugehörigen Metadaten ein weiterer 24b. Obwohl ich die Bildgröße in Zukunft vergrößern kann, sobald ich einen funktionierenden Prototyp habe.

Im Moment bin ich nicht in der Lage, dieses ganze Paket erfolgreich wiederherzustellen, da ich nach dem Senden an den PC immer nur ca. 64kb im Puffer erhalten habe.

Ich habe angenommen, dass dies für eine Buchse die Standardpuffergröße wie erklärt, weil aus irgendeinem Grund ist:

SOCKET sock = socket(PF_INET, SOCK_STREAM, 0); 

ist 64kb (bitte jemand dies klären könnte, wenn Sie ‚in der wissen‘ sind)

Also - um dieses Problem zu beheben, beabsichtige ich, die Socketgröße auf 1024kb über den Befehl setsockopt (x ..) zu erhöhen.

Bitte könnte jemand bestätigen, dass meine Diagnose des Problems und die vorgeschlagene Lösung korrekt sind?

Ich stelle diese Frage, da ich gerade von meinem PC weg bin und ich kann es nicht versuchen, bis ich wieder nach Hause komme.

+0

Die andere Alternative, für die ich mich geistig vorbereite, besteht darin, das Paket manuell zu segmentieren. Dies würde jedoch, wie ich vermute, viel mehr Fehlerpotential mit sich bringen und die Gesamtpaketgröße/Rechenzeit erhöhen, da ich für jedes einzelne Segment eine Kopfzeile senden und lesen müsste. –

+0

Es ist London zu einem Ziegel, dass der Grund, warum Sie nicht alle Daten erhalten, ist, dass Sie annehmen, dass 'recv()' Ihren Puffer füllt, anstatt zu loopen. Es gibt nichts in der Dokumentation, das diese Annahme stützt. – EJP

+0

Danke für die Antwort, nicht 100% sicher, dass ich dir folgen, aber um zu verdeutlichen: Ich kenne die Größe der eingehenden Daten, weil es in der Kopfzeile gespeichert ist und diese extrahiert, gelesen wird, und einen Puffer geeigneter Größe zugeordnet, um den Rest von zu empfangen die Daten. Also, in einem weiteren Erklärung: > Header holen mit Datenpaketgröße > Erstellen Puffer der richtigen Größe > Ausführen recv die Puffer und notieren Sie Bytes empfangen zu füllen> Überprüfen empfangenen Bytes gegen Datengröße in Kopf –

Antwort

0

Dies ist höchstwahrscheinlich nichts mit den Socket-Puffer zu tun, sondern mit der Tatsache, dass recv() und send() müssen nicht erhalten und alle Daten senden Sie wollen. Überprüfen Sie den Rückgabewert dieser Funktionsaufrufe, es zeigt an, wie viele Bytes tatsächlich gesendet und empfangen wurden.

Der beste Weg, mit „kurz“ beschäftigen liest/schreibt, ist sie in einer Schleife zu setzen, etwa so:

char *buf; // pointer to your data 
size_t len; // length of your data 
int fd;  // the socket filedescriptor 

size_t offset = 0; 
ssize_t result; 
while (offset < len) { 
    result = send(fd, buf + offset, len - offset, 0); 
    if (result < 0) { 
    // Deal with errors here 
    } 
    offset += result; 
} 

Verwenden Sie eine ähnliche Konstruktion zum Empfangen von Daten. Beachten Sie, dass eine mögliche Fehlerbedingung darin besteht, dass der Funktionsaufruf unterbrochen wurde (errno = EAGAIN oder). In diesem Fall sollten Sie den Sendebefehl wiederholen, in allen anderen Fällen sollten Sie die Schleife beenden.

+0

Danke @ G.Sliepen. Also, ich sehe, dass Sie in einer Schleife senden, und damit vorschlagen (bitte korrigieren Sie mich, wenn nicht), dass auf der Empfängerseite ein looping recv verwendet werden sollte.- Was ist der Schutz gegen das Einholen von Daten, die nicht beabsichtigt sind, wie ein zufälliges Paket, das von einem nicht verwandten Programm an den Port gesendet wird? Die einzige Möglichkeit, dies zu tun, wäre, eine Kopfzeile mit einer 'Teil 10 von 20' ID zu schreiben. Scheint dies nicht zu weiteren Problemen zu führen? - Ich meine, meine Hauptfrage ist, dass ich nicht nur die Größe des internen Systempuffers erhöhen kann, den send/recv verwendet? d. h. setsockopt ... –

+0

Ja, Sie sollten eine Empfangsschleife auf der Empfängerseite verwenden. TCP-Sockets (von denen ich annehme, dass Sie verwenden) stellen immer einen geordneten Datenstrom von einer einzelnen Verbindung bereit. Sie erhalten also keine falschen Daten von einer nicht verwandten Netzwerkverbindung, und Sie werden sehen, dass alle Daten in der gleichen Reihenfolge eingehen, in der sie gesendet wurden. –