2009-07-20 3 views
1

Ich versuche, ein Bild mithilfe von TCP-Sockets mit Linux zu übertragen. Ich habe den Code viele Male benutzt, um kleine Beträge zu übertragen, aber sobald ich versuchte, das Bild zu übertragen, übertrug es nur das erste Drittel. Ist es möglich, dass es eine maximale Puffergröße für tcp Sockets in Linux gibt? Wenn ja, wie kann ich es erhöhen? Gibt es eine Funktion, die das programmatisch macht?Übertragen eines Bildes mit TCP Sockets in Linux

+0

Wie viele Daten erhält es? – Javier

+1

Ich sende 800x600x3 (1440000 Bytes) und ich erhalte nur 65536 Bytes – DHamrick

+0

Haben Sie etwas Code? Denken Sie daran, dass TCP ein Stream und nicht nachrichtenorientiert ist. Ein Schreibaufruf benötigt möglicherweise mehrere Leseaufrufe zum Lesen. Oder mehrere Schreibanrufe benötigen möglicherweise nur einen Schreibaufruf zum Empfangen. Denken Sie daran, den Rückgabewert von write() zu überprüfen, es liegt in Ihrer Verantwortung, alle Daten zu schreiben, ein write() -Aufruf könnte nur Teile der Daten senden. – nos

Antwort

1

TCP sendet die Daten in Teilen, so dass Sie nicht mit einem einzigen Lesevorgang alles auf einmal bekommen (obwohl es in der Reihenfolge bleibt, in der Sie es senden). Sie müssen im Grunde mehrere Male lesen, bis Sie alle Daten erhalten. Es weiß auch nicht, wie viele Daten Sie auf der Empfängerseite gesendet haben. Normalerweise senden Sie zuerst ein "length" -Feld fester Größe (zum Beispiel immer 8 Bytes), damit Sie wissen, wie viele Daten es gibt. Dann lesen Sie weiter und erstellen einen Puffer, bis Sie so viele Bytes bekommen.

So der Sender so etwas wie dieser (Pseudo-Code) aussehen würde

int imageLength; 
char *imageData; 

// set imageLength and imageData 

send(&imageLength, sizeof(int)); 
send(imageData, imageLength); 

Und der Empfänger würde wie folgt aussehen (Pseudo-Code)

int imageLength; 
char *imageData; 

guaranteed_read(&imageLength, sizeof(int)); 
imageData = new char[imageLength]; 
guaranteed_read(imageData, imageLength); 

void guaranteed_read(char* destBuf, int length) 
{ 
    int totalRead=0, numRead; 
    while(totalRead < length) 
    { 
     int remaining = length - totalRead; 
     numRead = read(&destBuf[totalRead], remaining); 
     if(numRead > 0) 
     { 
      totalRead += numRead; 
     } 
     else 
     { 
      // error reading from socket 
     } 
    } 
} 

Offensichtlich verließ ich den eigentlichen Socket-Deskriptor aus und Sie brauchen um all das eine Menge Fehlerprüfung hinzuzufügen. Es sollte nicht vollständig sein, mehr um die Idee zu zeigen.

3

Ich würde vermuten, dass das Problem auf der Empfängerseite ist, wenn Sie aus dem Sockel lesen. TCP ist ein Stream-basiertes Protokoll, das keine Ahnung von Paketen oder Nachrichtengrenzen hat.

Dies bedeutet, wenn Sie einen Lesevorgang ausführen, erhalten Sie möglicherweise weniger Bytes als Sie anfordern. Wenn Ihr Bild beispielsweise 128 KB groß ist, erhalten Sie bei Ihrem ersten Lesevorgang möglicherweise nur 24 KB, sodass Sie erneut lesen müssen, um den Rest der Daten zu erhalten. Die Tatsache, dass es ein Bild ist, ist irrelevant. Daten sind Daten.

Zum Beispiel:

int read_image(int sock, int size, unsigned char *buf) { 
    int bytes_read = 0, len = 0; 
    while (bytes_read < size && ((len = recv(sock, buf + bytes_read,size-bytes_read, 0)) > 0)) { 
     bytes_read += len; 
    } 
    if (len == 0 || len < 0) doerror(); 
    return bytes_read; 
} 
0

Die maximale Größe für ein einzelnes IP-Paket ist 65535, das die Anzahl extrem nahe ist, die Sie zu treffen. Ich bezweifle, dass das ein Zufall ist.