2009-02-28 14 views
3

Ich habe eine C++ - Anwendung, die Bestandsdaten empfängt und über Socket an eine andere Anwendung weiterleitet (die als Server fungiert).Umgang mit Hochfrequenzdaten?

Tatsächlich ist die WSASend Funktion kehrt mit Fehlercode 10055 nach kleiner Sekunde und ich fand, dass die Fehlermeldung

„Kein Pufferraum zur Verfügung. Ein Vorgang auf einem Socket konnte nicht ausgeführt werden, weil das System Pufferspeicher fehlte oder weil eine Warteschlange voll war ".

Das Problem tritt nur auf, wenn ich die Anwendung nach den Marktstunden ausführen, da wir die ganzen Tag Daten (ca. 130 MB) in wenigen Minuten erhalten (ich nehme an, das ist relativ groß) Ich mache so einen Robustheitstest .

Ich versuchte, den Sendepuffer SO_SNDBUF mit setsockopt Funktion zu erhöhen, aber das gleiche Problem immer noch da. Wie kann ich dieses Problem lösen? hängt das mit dem Empfängerpuffer zusammen?

Senden Details:

Für jede vollständige Nachricht ich die Sendemethode aufrufen, die

EDIT überlappten Buchsen verwendet: Kann jemand allgemeine Richtlinien geben Hochfrequenzdaten in C++ zu behandeln?

+0

Wie warten Sie, bis jeder Sendevorgang abgeschlossen ist?Über eine IOCP-Benachrichtigung oder ein Ereignis in der OVERLAPPED-Struktur? –

+0

Ich denke, das ist das Problem :), ich warte nicht, bis die Sendefunktion beendet –

+0

Gute Sachen. Hoffe das behebt es für dich. –

Antwort

6

Die Ablaufsteuerung von TCP führt dazu, dass der interne Sendepuffer voll wird, wenn der Empfänger das Ende des Sockels nicht schnell genug verarbeitet. Es scheint aus der Fehlermeldung, dass Sie Daten senden, unabhängig davon, wie schnell der Winsock-Stapel es verarbeiten kann. Es wäre hilfreich, wenn Sie genau angeben könnten, wie Sie die Daten senden. Warten Sie, bis alle Daten ankommen und Sie einen großen Block senden oder Stück für Stück senden?

Senden Sie über eine nicht blockierende oder überlappende Buchse? In jedem Fall sollten Sie nach jedem Senden wahrscheinlich auf eine Benachrichtigung warten, dass der Socket in einem Zustand ist, in dem er mehr Daten senden kann, entweder weil select()/WaitForMultipleObjects() angibt (für nicht blockierende Sockets) oder Überlappende E/A abgeschlossen, wodurch signalisiert wird, dass die Daten erfolgreich in die internen Sendepuffer der Sockets kopiert wurden.

Sie können Sends überlappen, dh mehr als einen Puffer gleichzeitig in Warteschlange stellen - das ist es, wofür überlappende E/A verwendet wird - aber Sie müssen die Speicherauswirkungen beim Sperren einer großen Anzahl von Seiten sorgfältig berücksichtigen nicht ausgelagerter Pool

0

Nick's Antwort trifft ziemlich genau den Nagel auf den Kopf; Sie werden wahrscheinlich das Limit für "gesperrte Seiten" erschöpfen, indem Sie zu viele überlappende Sends gleichzeitig starten. Idealerweise müssen Sie Ihre Daten in Ihren eigenen Speicherpuffern puffern und nur jeweils eine festgelegte Anzahl überlappender Sends ausstehen lassen. Ich spreche darüber, wie Sie mit meinem IOCP-Framework können Sie mit dieser Art von Situation hier http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.html und die damit verbundenen TCP erhalten Fensterflusskontrolle Probleme hier http://www.lenholgate.com/blog/2008/06/data-distribution-servers.html und hier http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html.

Meine bevorzugte Lösung besteht darin, eine konfigurierbare Anzahl von überlappenden Sends zu einem Zeitpunkt zuzulassen und nach dem Überschreiten dieses Limits Daten zu puffern und dann die abgeschlossenen überlappenden Sends zu verwenden, um das Senden der gepufferten Daten zu steuern. Auf diese Weise können Sie den Umfang des nicht ausgelagerten Pools und die Anzahl der verwendeten gesperrten Seiten genau steuern und es ist möglich, dass viele Verbindungen so schnell wie möglich gesendet werden und dennoch die von ihnen verwendeten Ressourcen kontrolliert werden.