senden einer großen Menge von Daten über TCP-socket
Dies ist meine erste Frage gepostet auf diesem forum, und ich bin ein Anfänger in der c# Welt , so ist dies ziemlich aufregend für mich, aber ich bin vor einige Probleme mit dem senden einer großen Menge von Daten über sockets das ist also mehr details zu meinem problem:
Schicke ich ein binäres Bild von 5 MB über einen TCP-socket, auf dem empfangenden Teil bin ich das Ergebnis speichern(Daten empfangen ) und bekommen nur 1,5 Mo ==> Daten verloren gegangen sind (ich Vergleich das original und die erzeugte Datei und es zeigte mir die verpassten Teile)
dies ist der code den ich benutze:
private void senduimage_Click(object sender, EventArgs e)
{
if (!user.clientSocket_NewSocket.Connected)
{
Socket clientSocket_NewSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
user.clientSocket_NewSocket = clientSocket_NewSocket;
System.IAsyncResult _NewSocket = user.clientSocket_NewSocket.BeginConnect(ip_address, NewSocket.Transceiver_TCP_Port, null, null);
bool successNewSocket = _NewSocket.AsyncWaitHandle.WaitOne(2000, true);
}
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(Uimage_Data);
user.clientSocket_NewSocket.Send(outStream);
}
In Foren sagen Sie zu teilen Daten in chunks, ist das eine Lösung, wenn ja, wie kann ich dies tun, habe ich versucht, aber es hat nicht funktioniert!
InformationsquelleAutor user1767701 | 2012-10-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es viele verschiedene Lösungen, aber chunking ist in der Regel eine gute Lösung, können Sie entweder blind, wo Sie halten, füllen Sie Ihre temporären Puffer und dann setzen Sie es in einigen stateful-Puffer, bis Sie auf einem beliebigen token oder der Puffer ist nicht voll, oder können Sie sich auf eine Art von Vertrag per tcp Nachricht (eine Nachricht wird, die gesamten Daten zu erhalten).
Wenn Sie waren, zu betrachten, dabei eine Art von Vertrag, der dann etwas tut, wie die ersten N bytes einer Nachricht wird der Deskriptor, der Sie machen könnte so groß oder so klein, wie Sie wollen, aber dein temp-buffer NUR Lesen dieser Größe vorne aus dem stream.
Einem typischen header könnte etwas sein wie:
So würden Sie Lesen, daß dann, wenn seine klein genug, verteilen Sie die vollständige Nachricht die Größe der temp-Puffer und Lesen es alle, oder wenn Sie meinen, dass es zu großen teilen es in Abschnitte und Lesen, bis die Gesamtanzahl der bytes, die Sie erhalten haben, entsprechen die MessageSize Teil von deinem header-Struktur.
ja, ich hab Präfix mit "sowas" wie machte ich es, als ich getippt, guter Punkt, den Sie erhöhen obwohl.
InformationsquelleAutor Grofit
Wahrscheinlich, Sie haven ' T Lesen Sie die Dokumentation, die auf socket-Verwendung in C#. (http://msdn.microsoft.com/en-us/library/ms145160.aspx)
Den internen Puffer, kann nicht speichern alle Daten, die Sie senden methode. Eine mögliche Lösung für dein problem sein kann, wie Sie gesagt haben, teilen Sie Ihre Daten in chunks.
Send (buffer, flags)
überlastung. DieSend (buffer)
nicht, rufen Sie diese Einschränkung aus.In der Tat, Send(byte[] buffer,int offset,int size, SocketFlags socketFlags)
vielen Dank für die schnellen Antworten , ich hätte nicht erwartet, dass die Antwort so schnell wie du es getan hast 🙂 ich habe versucht, fast der Methoden, aber ich habe immer noch das gleiche problem, einige Daten fehlen noch, ich dachte, es hätte ein Verhältnis mit meinem Datei-Typ: es ist eine binäre Datei, so dass ich versuchte, senden von Datei.dat und es funktionierte gut. Meine Frage ist: Warum eine binäre Datei nicht versendet werden kann, ohne dabei einige Daten und wie kann ich den Prozess um dieses Problem zu beheben?? Danke 😉
Ich würde vorschlagen, veröffentlichen Sie Ihren client-code. Ähnlich wie Ihre server-code müssen Sie warten, bis Sie Ihre Erhalten die methode gibt 0 zurück, um sicherzustellen, dass alle Daten empfangen werden.
InformationsquelleAutor K Roobroeck
Ich vermute, dass eines deiner Probleme ist, dass Sie nicht aufrufen
EndConnect
. Aus der MSDN-Dokumentation:Auch, die warten:-
ist wohl immer falsch, da es nichts Einstellung, die das Ereignis in den signalisierten Zustand. In der Regel geben Sie eine callback-Funktion, die
BeginConnect
- Funktion und der callback würde manEndConnect
und der Zustand der das Ereignis signalisiert wird. Siehe Beispiel-code auf dieser MSDN-Seite.UPDATE
Ich glaube, ich sehe ein anderes problem:-
Ich weiß nicht, welche Art Uimage_Data aber ich glaube wirklich nicht, Sie wollen es zu konvertieren in ASCII-Darstellung. Eine null in die Daten signalisieren ein Ende des Daten-byte (oder vielleicht auch ein 26 oder someother ASCII-code). Der Punkt ist, die Kodierung ist wahrscheinlich, die Daten zu verändern.
Können Sie den Typ für die
Uimage_Data
Objekt?Die synchrone version hat kein timeout angegeben werden können, auch wenn der zugrunde liegende Anbieter timeout irgendwann.
vielen Dank für die schnellen Antworten , ich hätte nicht erwartet, dass die Antwort so schnell wie du es getan hast 🙂 ich habe versucht, fast der Methoden, aber ich habe immer noch das gleiche problem, einige Daten fehlen noch, ich dachte, es hätte ein Verhältnis mit meinem Datei-Typ: es ist eine binäre Datei, so dass ich versuchte, senden von Datei.dat und es funktionierte gut. Meine Frage ist: Warum eine binäre Datei nicht versendet werden kann, ohne dabei einige Daten und wie kann ich den Prozess um dieses Problem zu beheben?? Danke 😉
Ein update gemacht auf meine Antwort mit einem anderen möglichen problem mit dem code.
das ist, warum wir haben die SendTimeout Eigenschaft
InformationsquelleAutor Skizz
Wahrscheinlich das problem ist, dass Sie zum schließen der client-Seite socket, bevor alle Daten an den server übertragen, und es ist daher immer verworfen.
Standardmäßig, wenn Sie einen socket schließen, alle untransmitted Daten (sitzen in der Betriebssystem-Puffer) wird verworfen. Es gibt ein paar Lösungen:
[1] SO_LINGER (siehe http://developerweb.net/viewtopic.php?id=2982)
[2] die server-senden einer Bestätigung an den client, und schließen Sie nicht die client-Seite socket, bis Sie es erhalten.
[3] Warten Sie, bis der Ausgabepuffer leer ist auf der client-Seite vor dem schließen des socket (test mit getsocketopt SO_SND_BUF - ich bin nicht sicher über die syntax, die auf c#).
Außerdem sollte man das wirklich testen Sie den Rückgabewert von Send(). Obwohl in der Theorie sollte es zu blockieren, bis es die Daten sendet, ich würde wollen, um tatsächlich zu überprüfen, und mindestens eine Fehlermeldung ausgegeben, wenn es ein Ungleichgewicht gibt.
InformationsquelleAutor CpnCrunch
Nur eine Anmerkung: ich weiß nicht, was ein Mo ist; aber wenn es etwas mehr als 64 KB sind, dann sind Sie etwas falsch. TCP-Protokoll selbst hat Beschränkungen auf die Paketgröße. Der Höchstwert ist 64 KB, ABER KÖNNEN SIE NICHT ERREICHEN! Das ist, weil die maximale Größe eines Pakets auf unterschiedlichen Ebenen unterscheidet. "Die MTU (Maximum Transmission Unit) für Ethernet beispielsweise 1500 bytes."
TCP-Datenstrom-Protokoll; aber es bedeutet nicht, dass Ihr Netzwerk kann eigentlich mit dem, was Sie füttern, es ohne problem. "Aufgrund von Netzwerk-Staus, traffic-load-balancing oder anderen unvorhersehbaren Netzwerk-Verhalten, IP-Pakete können verloren gehen, dupliziert oder gelieferte out of order"; dieser Teil wird meist über die IP im "Internet-Schicht" vergleichen TCP ist ein Protokoll, das auf der "Transport layer". Wenn Sie sich für die 2 GB haben, dann wird ip-Fragmentierung und Daten-Verlust; also eigentlich werden Sie nie bekommen Sie Ihre 2 GB Daten heruntergeladen, ohne dass ein download-manager (z.B.) der Protokolle für das streaming von Daten (@Application Layer 🙂
InformationsquelleAutor Kaveh Shahbazian