ubuntuusers.de

P2P - Netzwerkprogrammierung in C++

Status: Ungelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

Giesi35

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Hallo,

ich habe folgendes Problem: Ich soll ein P2P-Clienten in C++ schreiben, welcher einfache Daten (strings) austauscht. Auf Server/Clienten-Basis ist das auch kein Problem, allerdings hänge ich jetzt beim P2P-Netzwerk. Als Protokol dient hier UDP. Ich bin relativ ratlos wie ich an das ganze rangehen soll.

Hier die Headerdateien mit dem man doch was anfangen könnte:

socket.h

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
/******************************************
* socket.h
*
* Verwaltet Sockets fuer Server und Clients
*
******************************************/

#ifndef _INC_SOCKET
#define _INC_SOCKET

#ifndef POSIX
#pragma comment(lib, "Ws2_32.lib")
#include <WinSock2.h>
#else /* POSIX-Systeme wie LINUX */
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#endif

#include <sys/types.h>
#include <string>
#include <sstream>

/** Protokoll-Typen */
enum PROTOCOL_TYPE
{
	TCP_IP		= 0, // TCP-IP (v4)
	TCP_IPV6	= 1, // TCP-IP (v6)
	UDP			= 2  // UDP
};

/**
Socket:

Verarbeitet den Umgang mit Sockets
**/
class Socket
{
private:

/** einige WinSock2-Sachen (nur Windows)*/
#ifdef WIN32
	void Start();
	void End();
#endif /* WIN32 */

protected:
	/** Server und Client sind Freunde */
	friend class Client;
	friend class Server;

	/** c'tor - Nimmt TCP als Protokol an */
	Socket();
	/** c'tor welcher nur von erbenden Klassen aufgerufen werden kann */
	Socket(PROTOCOL_TYPE type);
	/** c'tor mit initialisierten Socket */
	Socket(SOCKET sock);

	/** Unser Socket */
	SOCKET _sock;

public:
	/** Copy-Constructor */
	Socket(const Socket& cpy_socket);
	/** Zuweisungs-Operator ueberladen */
	Socket& operator= (Socket& SocketB);
	/** d'tor */
	virtual ~Socket();

	/**	
	Erhaelt einen String und gibt diese zurueck
	SignOfEnd - Zeichen, bei welchem der Empfang abbricht und der String zurueckgegeben wird
	**/
	std::string ReceiveString(char SignOfEnd);
	/** Sendet einen String **/
	void SendString(std::string to_send);

	/** Schliesst Socket **/
	void Close();
};

/**
* Singleton-Instanz
* Checkt ob ein Port verfuegbar ist
**/
class PortScan
{
private:
	// private c'tors
	PortScan() {}
	PortScan(const PortScan& obj) {}
	~PortScan() {}

public:
	// Unsere Instanz
	inline static PortScan& GetInstance()
	{
		static PortScan Instance;
		return Instance;
	}

	/** Scannt einen Port. Gibt true zurueck wenn Port belegt, andernfalls false */
	bool Scan(int Port);
};

#endif /* _INC_SOCKET */

client.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/******************************************
* client.h
*
* Verwaltet den Clienten
*
******************************************/

#ifndef _INC_CLIENT
#define _INC_CLIENT

#include "socket.h"
#include <string>
#include <sstream>

/** Verwaltet Clienten */
class Client : public Socket
{
public:
	/** c'tor welcher Client erstellt */
	Client(std::string host, int Port, PROTOCOL_TYPE type);
};

#endif /* _INC_CLIENT */

server.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/******************************************
* server.h
*
* Verwaltet den Server
*
******************************************/

#ifndef _INC_SERVER
#define _INC_SERVER

#include "socket.h"

#include <string>
#include <sstream>

/** Verwaltet Server */
class Server : public Socket
{
public:
	/** c'tor - Erstellt den Server mit angegebener Portnummer */
	Server(int port, PROTOCOL_TYPE type);

	/** Aktzeptiert Verbindung */
	Socket* Accept();
};

#endif /* _INC_SERVER */

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

ich habe folgendes Problem: Ich soll ein P2P-Clienten in C++ schreiben, welcher einfache Daten (strings) austauscht.

Der Witz an P2P-Systemen ist ja grad, dass es keine Trennung in Client und Server gibt¹ - insofern ist Deine Aussage in sich unschlüssig.

Ganz im Ernst: Man muss sich für so etwas doch erst einmal ein Protokoll "ausdenken"; das haben jedoch schon viele kluge Köpfe gemacht und es gibt für diese Konzepte auch schon fertige Libs. Also anstelle von Null anzufangen, solltest Du auf ein bestehendes System aufsetzen. Je nach Anwendungsfall gäbe es da verschiedene Ansätze:

  • BitTorrent: Wenn Du große Dateien austauschen willst und hohe Redundanz erwünscht ist

  • CHORD / Pastry: Sehr gute Ansätze für strukturierte P2P-Systeme. Schnelles und vor allem exaktes Suchen.

  • Gnutella: Simpel aber sinnlos 😉

Also würde ich an Deiner Stelle mal nach diesen Konzepten suchen und mir eine geeignete Lib dafür heraussuchen und nutzen.

¹ Es gib natürlich "Mischformen"; im Idealfall ist jedoch jeder Peer exakt gleichberechtigt mit jedem anderen. Dennoch würde ich nie von einem P2P-Client sprechen und habe das in der Literatur auch noch nie gelesen.

Giesi35

(Themenstarter)

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Lysander schrieb:

Giesi35 schrieb:

ich habe folgendes Problem: Ich soll ein P2P-Clienten in C++ schreiben, welcher einfache Daten (strings) austauscht.

Der Witz an P2P-Systemen ist ja grad, dass es keine Trennung in Client und Server gibt¹ - insofern ist Deine Aussage in sich unschlüssig.

Falsch formuliert meinerseits. Mit "P2P-Clienten" meinte ich ein Programm welches per P2P mit anderen kommuniziert!

Ganz im Ernst: Man muss sich für so etwas doch erst einmal ein Protokoll "ausdenken"; das haben jedoch schon viele kluge Köpfe gemacht und es gibt für diese Konzepte auch schon fertige Libs. Also anstelle von Null anzufangen, solltest Du auf ein bestehendes System aufsetzen. Je nach Anwendungsfall gäbe es da verschiedene Ansätze:

  • BitTorrent: Wenn Du große Dateien austauschen willst und hohe Redundanz erwünscht ist

  • CHORD / Pastry: Sehr gute Ansätze für strukturierte P2P-Systeme. Schnelles und vor allem exaktes Suchen.

  • Gnutella: Simpel aber sinnlos 😉

Also würde ich an Deiner Stelle mal nach diesen Konzepten suchen und mir eine geeignete Lib dafür heraussuchen und nutzen.

¹ Es gib natürlich "Mischformen"; im Idealfall ist jedoch jeder Peer exakt gleichberechtigt mit jedem anderen. Dennoch würde ich nie von einem P2P-Client sprechen und habe das in der Literatur auch noch nie gelesen.

Es ist gewollt das man bei 0 anfängt! Zudem wäre es sehr überladen für diese einfache Funktion dicke libs zu linken!

Ganz bei 0 ist es ja nicht. Server/Client-Klassen funktionieren ja. Und da P2P nichts anderes ist, wie jeder ist Server/Client dürfte man ja genau dort an-/aufsetzen!

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

Es ist gewollt das man bei 0 anfängt!

Aha. Dann frage ich mich jetzt, wo Dein Konzept ist? Wie soll denn das Routing funzen? Das ist ja letztlich das zentrale Thema bei P2P-Netzwerken.

Zudem wäre es sehr überladen für diese einfache Funktion dicke libs zu linken!

Naja, einfach ist relativ... schau Dir mal CHORD an, da muss man schon ein wenig dran grübeln, bis man den Clou verstanden hat. Zudem ist das Erstellen und Pflegen einer Routingtabelle unabhängig vom eigentlichen Routing-Algo nicht trivial. Zudem sollte man imho generell immer auf Bestehendes aufsetzen, außer man hat gute Gründe, die dagegen sprechen. "Dicke Lib" und "lohnt sich nicht für eine simple Funktionalität" zähle ich nicht dazu 😉

Ganz bei 0 ist es ja nicht. Server/Client-Klassen funktionieren ja. Und da P2P nichts anderes ist, wie jeder ist Server/Client dürfte man ja genau dort an-/aufsetzen!

P2P ist eben weit mehr! Natürlich muss ein Peer mit einem anderen per TCP / UDP o.ä. kommunizieren können - aber die eigentliche Kunst ist ja das Overlay-Netzwerk, welches durch den Routingmechanismus entsteht. Und das kann eben durchaus komplex sein. Aber nach dem Konzept fragte ich ja schon oben 😉

Ich kenne jetzt den Rahmen des Projektes nicht (Uni? Schule? Abschlussarbeit? Job?), aber das ganze wirkt mir ein wenig planlos, da die zentrale Fragestellung bisher wohl nicht erkannt wurde. Bevor Du da drauf los programmierst, solltest Du evtl. das noch mal abklären. Oder weißt Du da mehr, als Du uns bisher verraten hast?

Giesi35

(Themenstarter)

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Uni.

Aufgabe: P2P-System. Der Client soll Daten besitzen und von anderen, die solche Daten besitzen, einsammeln und ausgeben.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

Aufgabe: P2P-System. Der Client soll Daten besitzen und von anderen, die solche Daten besitzen, einsammeln und ausgeben.

Na die Aufgabe wird doch sicher ein wenig detaillierter gestellt sein 😉

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

Giesi35 schrieb:

Uni.

Aufgabe: P2P-System. Der Client soll Daten besitzen und von anderen, die solche Daten besitzen, einsammeln und ausgeben.

Hm das ist noch etwas dünn. Ich gehe davon aus das in deiner Aufgabenbeschreibung noch mehr steht? Ohne deine Hausaufgaben jetzt machen zu wollen:

  • Für den Fall, das alle deine Systeme in der gleichen IP Broadcastdomain stehen, sollte sich UDP Broadcast sinnvoll einsetzen lassen.

  • Falls Broadcast nicht in Frage kommt kannst du evtl. Multicast benutzen. Wenn dein Netz mehr als ein IP Subnetz umspannt brauchst du dafür natürlich Router die entsprechende Multicastroutingprotokolle beherrschen. Denk dir eine Multicatsgruppe aus, lass alle deine Clients dieser beitreten und sende deine Pakete an diese Gruppe.

  • Wenn keine dieser Lösungen möglich ist, dann brauchen wir mehr Input, was die Aufgabenstellung von dir eigentlich erwartet.

  • Um das entsprechende Protokoll ("Hallo, wer hat welche Daten?", "Schick mir dieses oder jenes!" oder wie auch immer du es ansetzt) darfst du dich dann alleine kümmern.

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

Lysander schrieb:

Giesi35 schrieb:

Aufgabe: P2P-System. Der Client soll Daten besitzen und von anderen, die solche Daten besitzen, einsammeln und ausgeben.

Na die Aufgabe wird doch sicher ein wenig detaillierter gestellt sein 😉

Den simpelsten Fall habe ich noch vergessen: die Menge der Teilnehmer ist konstant und allen bekannt. Jeder kann direkt mit jedem anderen kommunizieren. Alle kommunizieren direkt miteinander.

Wie gesagt, ohne Kenntnis der Aufgabenstellung und der vorausgesetzten Umgebung kann das von simpel bis beliebig komplex werden.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Neben dem bisher gesagtem würde ich ebenfalls vorschlagen, nicht alles auf unterster Ebene zu realisieren. Ok, wenn Du doch noch eine fertige Lib nutzt, dann erübrigt sich das, da die Netzwerkkommunikation dann schon gekapselt zur Verfügung steht. Ansonsten würde ich aber auf gute Libs zurückgreifen, wie QtNetwork oder auch Boost.Asio. Ggf. kann man sogar noch höher abstrahieren und alles über xmlrpc / jsonrpc regeln.

Giesi35

(Themenstarter)

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Zur Simulation ist die IP 127.0.0.1 also alle Clients auf der lokalen Maschine von beispielsweise Port 50001 ... 50010.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

Zur Simulation ist die IP 127.0.0.1 also alle Clients auf der lokalen Maschine von beispielsweise Port 50001 ... 50010.

Ja und? Was bringt denn diese Info?

Ehrlich gesagt geizt Du mir auch zu sehr mit Kommentaren. Du gehst auf die zig gemachten Vorschläge, Ratschläge und Nachfragen nicht ein, sondern knallst hier nur einen Satz rein, der eigentlich zunächst wenig zielführend ist. Auf diese Weise wirst Du hier nicht viel Hilfe bekommen, da Du - neben der induzierten Demotivation beim potenziellen Helfer - einfach nicht genügend Infos geliefert hast.

Giesi35

(Themenstarter)

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Es ging um weitere Informationen zur Topic. Die wollte ich nurnoch bringen! Das ich mit Kommentaren "geize", liegt daran, dass ich mich wahrscheinlich nicht die ganze Zeit darum kümmern kann und mich damit befassen muss! Das soll nicht heißen, dass ich nicht dankbar bin..keineswegs, im Gegenteil!

Ich nehme die Vorschläge schon auf. Ich möchte auch keinen ewig langen Kommentar daraus machen, wäre auch Offtopic.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

Es ging um weitere Informationen zur Topic. Die wollte ich nurnoch bringen!

Die aber in keinem direkten Zusammenhang zu den Postings zuvor stehen.

Das ich mit Kommentaren "geize", liegt daran, dass ich mich wahrscheinlich nicht die ganze Zeit darum kümmern kann und mich damit befassen muss!

Du willst doch Hilfe!?! Insofern sollte man sich als Hilfesuchender schon ausreichend kommunikativ geben. Natürlich musst Du nicht 5 Minuten nach einem Posting hier antworten; aber wenn Du dann dazu kommst, solltest Du eben auf Nachfragen, Hinweise usw. eingehen.

Ich nehme die Vorschläge schon auf. Ich möchte auch keinen ewig langen Kommentar daraus machen, wäre auch Offtopic.

Das musst Du auch nicht. Es muss aber hinreichend präzise sein. Wir haben bisher ja noch null Feedback, welchen Hinweisen Du nachgehst. Alleine das dürfte jeden anderen Mitleser abschrecken auch nur noch irgend etwas konstruktives hier rein zuschreiben. Wie auch - niemand weiß ja bisher wirklich, wo es nun noch klemmt 😉

Antworten |