C ++ Winsock P2P

8

Szenario

Hat jemand gute Beispiele für Peer-to-Peer-Netzwerke (P2P) in C ++ mit Winsock? Es ist eine Anforderung, die ich für einen Kunden habe, der diese Technologie speziell nutzen muss (weiß Gott warum). Ich muss feststellen, ob dies machbar ist.

Jede Hilfe würde sehr geschätzt werden.

BEARBEITEN

Und ich möchte vermeiden, Bibliotheken zu verwenden, damit ich den zugrunde liegenden Quellcode und mein Wissen besser verstehen kann.

    
Goober 16.05.2010, 10:00
quelle

2 Antworten

35

Da ich nicht weiß, nach welchen Informationen Sie suchen, werde ich versuchen zu beschreiben, wie man ein Socket-Programm aufbaut und welche Fallstricke ich habe.

Beginnen Sie mit das Winsock-Lernprogramm von MSDN. Dies ist ein grundlegendes Programm zum Verbinden, Senden einer Nachricht und Trennen der Verbindung. Es ist großartig, um ein Gefühl für Socket-Programmierung zu bekommen.

Damit starten wir:

Überlegungen:

blockiert oder nicht blockiert

Zunächst müssen Sie feststellen, ob Sie ein blockierendes oder nicht blockierendes Programm wünschen. Der große Unterschied ist, dass Sie, wenn Sie eine GUI haben, nicht-blockierende oder Threading verwenden müssen, um das Programm nicht einzufrieren. Die Art und Weise, wie ich es gemacht habe, war, die blockierenden Aufrufe zu benutzen, aber immer select vor dem Aufruf der blockierenden Funktionen aufzurufen (mehr bei Auswahl später). Auf diese Weise vermeide ich Threading und Mutex und so weiter, aber benutze immer noch die grundlegenden Aufrufe accept , send und receive .

Sie können sich nicht darauf verlassen, dass Ihre Pakete so ankommen, wie Sie sie gesendet haben!

Sie haben auch keinen Einfluss darauf. Dies war das größte Problem, mit dem ich konfrontiert wurde, im Grunde, weil die Netzwerkkarte entscheiden kann, welche Informationen gesendet werden und wann sie gesendet werden sollen. Die Art und Weise, wie ich es gelöst habe, bestand darin, ein networkPackageStruct zu erstellen, das ein size und data enthält, wobei Größe der Gesamtumfang der Daten in diesem Paket ist. Beachten Sie, dass eine Nachricht, die Sie senden, in zwei oder mehr Nachrichten aufgeteilt werden kann und auch mit einer anderen von Ihnen gesendeten Nachricht zusammengeführt werden kann.

Betrachten Sie Folgendes: Sie senden zwei Nachrichten

%Vor%

Wenn Sie diese zwei Nachrichten mit der Funktion send senden, wird Ihre recv -Funktion möglicherweise nicht so angezeigt. Es könnte so aussehen:

%Vor%

oder vielleicht

%Vor%

wie das zugrunde liegende Netzwerk sich anfühlt ..

Log (fast) alles!

Das Debuggen eines Netzwerkprogramms ist schwierig, weil Sie nicht die volle Kontrolle darüber haben (da es sich um zwei Computer handelt). Wenn Sie eine blockierende Operation ausführen, können Sie sie auch nicht sehen. Dies könnte auch als "Kenne deinen Blockcode" bezeichnet werden. Wenn eine Seite etwas sendet, weißt du nicht, ob sie auf der anderen Seite ankommt, also behalte im Auge, was gesendet wird und was empfangen wird.

Achten Sie auf Socket-Fehler

Winsock-Funktionen geben viele Informationen zurück. Kenne deine WSAGetLastError() Funktion. Ich werde es in den folgenden Beispielen nicht behalten, aber beachte, dass sie dazu neigen, viele Informationen zurückzugeben. Jedes Mal, wenn Sie ein SOCKET_ERROR oder INVALID_SOCKET erhalten, überprüfen Sie die Winsock-Fehlermeldungen Nachschlagen

Einrichten der Verbindung:

Da Sie keinen Server wünschen, benötigen alle Clients einen empfangenden Socket, um neue Verbindungen zu akzeptieren. Das einfachste ist:

%Vor%

Das INADDR_ANY ist großartig - es lässt Ihren Socket tatsächlich in allen Ihren Netzwerken hören, statt nur eine IP-Adresse.

%Vor%

hier kommt der interessante Teil. bind und listen werden nicht blockiert, aber accept wird. Der Trick besteht darin, mit select zu prüfen, ob eine eingehende Verbindung besteht. Der obige Code dient nur dazu, den Socket zu setzen. In Ihrer Programmschleife suchen Sie nach neuen Daten im Socket.

Daten austauschen

Wie ich es gelöst habe, war es, select viel zu verwenden. Im Grunde sehen Sie, ob Sie auf irgendeinen Ihrer Sockets reagieren müssen. Dies geschieht mit den Funktionen FD_xxx .

%Vor%

in newSocket haben Sie jetzt einen neuen Partner. Also das war für den Empfang von Daten. Aber beachte! send blockiert ebenfalls! Einer der "Head Scratching Errors" war, dass send mich blockierte. Dies wurde jedoch auch mit select gelöst.

%Vor%

Herunterfahren

Schließlich gibt es zwei Möglichkeiten zum Herunterfahren. Entweder trennen Sie einfach, indem Sie Ihr Programm schließen, oder Sie rufen die Funktion shutdown auf.

  • Beim Aufruf von shutdown wird Ihr Peer select trigger aktiviert. recv empfängt jedoch keine Daten, sondern gibt stattdessen 0 zurück. Ich habe keinen anderen Fall bemerkt, in dem recv 0 zurückgibt, also ist es (etwas) sicher zu sagen, dass dies als Shutdown-Code betrachtet werden kann. % cco_de% aufzurufen, ist am nettesten.
  • Das Herunterfahren der Verbindung ohne Herunterfahren ist kaltherzig, funktioniert aber natürlich. Sie müssen den Fehler auch dann noch behandeln, wenn Sie shutdown verwenden, da es möglicherweise nicht Ihr Programm ist, das die Verbindung schließt. Ein guter Fehlercode ist 10054, der WSAECONNRESET lautet: Verbindung wurde von Peer zurückgesetzt. .
Default 27.05.2010, 11:49
quelle
2

Wenn Sie nur eine P2P-Anwendung unter Microsoft Windows implementieren möchten, können Sie es mit Windows Peer-to versuchen -Peer Networking

Wenn Sie ein eigenes P2P-Protokoll implementieren möchten, können Sie das eMule-Protokoll und den eMule-Quellcode studieren . Sie könnten weiter machen, wenn Sie in Shareaza Quellcode schauen, es eMule / Guntella / Gnutella / BitTorrent.

    
Yi Zhao 18.05.2010 06:02
quelle