Client-Server-Socket Programmierung: Unterstützung in unterschiedlichen Programmiersprachen

Mit Fallbeispielen


Travail d'étude, 2013

31 Pages, Note: 2.0


Extrait


Inhalt

1 Einführung
1.1 OSI-Modell
1.2 TCP/IP
1.2.1 IPv
1.2.2 IPv
1.2.3 Transmission Control Protocol
1.3 Verbindungen
1.4 Portnummern
1.5 User Datagram Protocol
1.6 Domain Name System
1.6.1 Aufbau des DNS
1.6.2 Namensauflösung
1.7 Sicherheit
1.7.1 Transport Layer Security
1.7.2 Hypertext Transfer Protokoll

2 Grundlagen von Sockets
2.1 Arten von Sockets
2.2 Ablauf der Socket-Kommunikation
2.3 Nützliche Tools
2.3.1 Netstat
2.3.2 Netcat

3 Implementierung von Sockets
3.1 Eine einfache Client-Anwendung in C
3.2 Eine einfache Server-Anwendung in C
3.3 Cross-Plattform-Development in C und C++
3.4 Cross-Plattform-Development in Java
3.4.1 Allgemeines
3.4.2 Klassen und Methoden der Java-Standard-API
3.5 Vom Sockets zum Port-bindender Shellcode
3.6 Sicherheit

4 Literaturverzeichnis

Abbildungsverzeichnis

Abbildung 1: Windows Cross-Plattform Echo-Server

Abbildung 2: Linux Cross-Plattform Echo-Server

Abbildung 3: Screenshots der Anwendung (1)

Abbildung 4: Screenshots der Anwendung (2)

Abbildung 5: UML-Diagramm

Tabellenverzeichnis

Tabelle 1: OSI-Modell

Tabelle 2: Wichtige Portnummern

Tabelle 3: HTTP-Methoden

Snippets

Formel 1: C socket()

Formel 2: C Connect()

Formel 3: C Send()

Formel 4: C Bind()

Formel 5: C Listen()

Formel 6: C Accept()

Formel 7: Windows WSA

Formel 8: Java Herstellen einer Verbindung – Serverseite

Formel 9: Java Herstellen einer Verbindung – Clientseite

Formel 10: Java Senden von Nachrichten mithilfe eines PrintWriters

Formel 11: Java Empfangen von Nachrichten mithilfe eines BufferedReaders

Formel 12: Java Senden von Objekten mithilfe eines ObjectOutputStreams

Formel 13: Java Empfangen von Objekten mithilfe eines ObjectInputStreams

Formel 14: Socket Funktion

Formel 15: Bind Funktion

1 Einführung

1.1 OSI-Modell

Das OSI-Modell (Open Systems Interconnection) ist ein Modell der International Organization for Standardization (ISO) zur Standardisierung der Kommunikation in Rechnernetzen. Es ordnet gegebene Dienste einer von sieben Schichten zu, wobei Dienste einer höheren Schicht die Dienste der darunterliegenden Schicht aufrufen können. Zum Beispiel kann ein Dienst der eine eindeutige Identifizierung von Netzwerkgeräten bereitstellt von der höheren Schicht aufgerufen werden um Daten an ein so identifiziertes Netzwerkgerät zu senden.

In 1 werden die Schichten des OSI-Modells aufgeführt. Diese werden im Folgenden erläutert:

1. Die Physikalische Schicht überträgt die eigentlichen Bits über das Kommunikationsmedium. Dabei kümmert sie sich um die physikalischen und elektrischen Eigenschaften des Mediums. Dazu gehören Dinge wie die korrekte Sendeleistung, welches Medium verwendet wird (z.B. Licht bei Glasfaserkabeln oder elektrische Signale bei Kupferkabeln) oder die genaueren Spezifikationen des Kabels.
Die physikalische Schicht stellt damit eine abstrakte Schnittstelle zur Verfügung mit der einzelne Frames über ein Kabel an eine horchende Gegenstelle gesendet oder von einer solchen empfangen werden können. Sie selbst arbeitet Bitorientiert.
2. Die Sicherungsschicht überträgt einzelne Frames fehlerfrei zu einer Gegenstelle oder empfängt Frames fehlerfrei von dieser. Ist dies nicht möglich, wird ein Fehler an die höhere Schicht weitergegeben. Ein Frame ist ein einheitlich großer Block von zu übertragenden Bits. Um die fehlerfreie Übertragung gewährleisten zu können werden den Frames Prüfsummen und ggfs. auch Fehlerkorrektur-Codes hinzugefügt.
Der Unterschied besteht darin, dass Prüfsummen zwar einen wesentlich geringeren Overhead benötigen, aber Fehler auch nur erkannt werden können. Bei Fehlerkorrektur-Codes ist es zudem auch möglich, Fehler zu korrigieren.
Zudem stellt die Sicherungsschicht eine physikalische Identifizierung der Netzwerkgeräte bereit. Diese wird jedem Gerät fest zugewiesen und soll nicht geändert oder auf ein anderes Gerät übertragen werden.
3. Die Netzwerkschicht überträgt Datenpakete von einem Netzwerkgerät zu einem anderen, wobei auch mehrere Zwischenstationen möglich sind, und stellt eine logische Identifizierung bereit. Eine logische Identifizierung ist keinem Gerät fest zugeordnet und kann geändert, sowie mehreren Geräten gleichzeitig oder nacheinander zugeordnet werden.
Um Datenpakete zu einem Netzwerkgerät zu übertragen ist es notwendig die möglichen Routen im Netzwerk in so genannten Routingtabellen festzuhalten. Dies kann statisch eingetragen werden, wird heute aber normalerweise dynamisch erledigt.
Ein Paket besteht aus einem Datensatz, einer Quelle, einem Ziel und einer Laufnummer und hat eine variable Länge.
4. Die Transportschicht dient der Segmentierung des Datenstroms und die Vermeidung von Datenstaus. Bei einem Datenstau kommen mehr Pakete bei einem Gerät an, als dieses verarbeiten kann. Meist passiert dies dadurch, dass eine große Zahl von anderen Geräten einen Pfad im Netzwerk (eine Route) gewählt haben, der über das überforderte Gerät führt. In der Transportschicht werden solche Staus erkannt und alternative Routen gewählt.
5. Die Session-Schicht stellt einen abstrakten Kommunikationskanal zwischen zwei Benutzern bereit. Dazu kümmert sie sich um den Verbindungsauf und -abbau, die Fehlererkennung auf Verbindungsebene, die Neuübertragung bereits gesendeter Daten im Fehlerfall und managt den Verbindungsablauf.
Mit Hilfe der Session-Schicht können darüber liegende Schichten beliebige Daten an Benutzer senden ohne sich darum kümmern zu müssen, ob die Daten auf dem Weg teilweise verloren gehen oder wie groß die einzelnen Pakete sein dürfen.
6. Die Darstellungsschicht kümmert sich um die Konvertierung syntaktisch unterschiedlicher Daten untereinander. Zudem werden hier nur zur Übertragung verwendete Datenformate gepackt und entpackt.
Insbesondere kümmert sich die Darstellungsschicht um die Verschlüsselung und die Kompression der Daten. Zudem können zum Beispiel Windows-Zeilenendungen in Unix-Zeilenendungen konvertiert werden wenn ein Windows mit einem Unix Rechner kommuniziert.
7. Die Anwendungsschicht stellt die Anwendungsdienste des Netzwerks bereit und ermöglicht dem Benutzer und Anwendungsprogrammen Zugriff auf das Netzwerk. In der Anwendungsschicht werden u.a. die Kommunikationspartner identifiziert und die notwendigen Ressourcen geholt.

Ein typischer Dienst in der Anwendungsschicht ist HTTP: Dieser holt eine Webseite von einem Webserver, identifiziert alle darin enthaltenen Ressourcen und holt diese ebenfalls vom Webserver.

Ein anderes Beispiel ist DNS: Dieses ermittelt zu einer gegebenen Domain (etwa htw-aalen.de) die zugehörige logische Adresse und identifiziert damit den Kommunikationspartner für diese Domain.

Beide Dienste werden im Folgenden noch näher besprochen.

Bei einem Sendevorgang werden die Schichten von oben her (also in der Reihenfolge 7, 6, 5, 4, 3, 2, 1) durchlaufen, bei einem Empfangsvorgang werden die Schichten von unten her durchlaufen.

Bestimmte Geräte, wie etwa Router, implementieren nicht alle Schichten, sondern können selbst in das OSI-Modell eingeordnet werden und müssen deshalb auch nur ihre eigene Schicht, sowie die Schichten darunter unterstützen.

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 1: OSI-Modell

1.2 TCP/IP

Das Internet Protocol (IP) ermöglicht die logische Adressierung von Netzwerkgeräten im Netzwerk. Aktuell dominiert die Version vier den Markt, allerdings wird aufgrund konzeptioneller Einschränkungen im Design von IPv4 ein globaler Umstieg auf IPv6 angestrebt. Der Marktanteil von IPv6 ist allerdings noch gering.

Bei IP wird jedem Netzwerkgerät eine logische Adresse, die IP-Adresse, zugewiesen. Diese ist (normalerweise) weltweit eindeutig, kann allerdings gewechselt werden und auch nacheinander mehreren Geräten zugewiesen werden. Ebenso ist es möglich, einem Gerät mehrere IP-Adressen zuzuweisen oder eine IP-Adresse mehreren Geräten zuzuweisen.

1.2.1 IPv4

Eine IP-Adresse ist bei IPv4 32 Bit lang und wird normalerweise im Format xxx.xxx.xxx.xxx notiert. Dabei ist xxx jeweils eine Dezimalzahl von 0 bis 255. Dadurch gibt es theoretisch etwa 4 Milliarden nutzbare IPv4-Adressen. Allerdings ist der nutzbare Adressraum in der Praxis deutlich kleiner, da sich durch die Konzeption von IPv4 ein erheblicher „Verschnitt“ ergibt (Mehr dazu im Abschnitt). IP spezifiziert einen Header, den jedes IP-Paket trägt und in dem Informationen wie die Quell- und Zieladresse, die verbleibende „Lebenszeit“ des Pakets, Prüfsummen und anderes übermittelt werden. Die „Lebenszeit“ bestimmt, wie oft ein Paket weitergeleitet wird, bevor es verworfen wird. Dadurch können endlos kreisende Pakete vermieden werden. Auf den Aufbau dieses Headers wird hier allerdings nicht näher eingegangen.

IPv4-Adressen werden von der ICANN an die Organisationen RIPE (zuständig für Europa und Nordafrika), APNIC (zuständig für Asien) und ARIN (zuständig für die restliche Welt) vergeben. Diese vergeben sie weiter an Internet Service Provider, welche sie wiederum ihren Kunden zur Verfügung stellen.

1.2.1.1 IPv4-Netzklassen

IPv4 ordnet jede IP-Adresse einem Netzwerk zu. Diese Netzwerke besitzen eine eigene Adresse und einen Adressraum. Die Entwickler von IPv4 sahen zunächst vor, jedes Netzwerk einer von drei Klassen angehören sollte. Anhand dieser Klasse wird die IP-Adresse in eine Netzwerk- und eine Geräte-Adresse geteilt. Bei Klasse A-Netzen bilden die ersten acht Bit die Netzwerkadresse, wobei das erste Bit immer eine 1 ist, und die folgenden 24 Bit die Geräte-Adresse. Dadurch gibt es 126 Klasse A-Netze mit jeweils 16.777.214 IP-Adressen. Bei Klasse B-Netzen sind die ersten 16 Bit die Netzwerkadresse, deren erste zwei Bit sind auf 10 gesetzt und die folgenden 16 Bit sind die Geräteadresse. Dadurch ergeben sich 16.382 Klasse B-Netzwerke mit jeweils 65.534 IP-Adressen. Bei Klasse C-Netzwerken sind die ersten drei Bits auf 110 gesetzt und gehören zu einer 24-bittigen Netzwerkadresse, die von einer 8-Bit Geräteadresse gefolgt wird. Dadurch sind 2097150 Klasse C-Netze mit jeweils 254 IP-Adressen möglich.

Bei jedem Netz ist jeweils die erste Adresse, deren Geräte-Adresse vollständig aus Nullen besteht, als Adresse des Netzwerks und die letzte, deren Geräteadresse vollständig aus Einsen besteht, als Broadcast-Adresse reserviert. Auf der Broadcast-Adresse kann eine Nachricht an alle Teilnehmer des Netzwerks gesendet werden.

Da bei dem starren Klassenschema auch einer Organisation, die nur wenig mehr als z.B. die 254 in einem Klasse C-Netz möglichen Geräte betreibt gleich ein Netz der nächsthöheren Netzklasse zugewiesen werden muss entsteht hier ein großer Verlust an praktisch nicht nutzbaren IP-Adressen. Da das Internet allerdings zu einer nicht vorausgesehenen Größe angewachsen ist, ist in letzter Zeit eine Knappheit von IP-Adressen eingetreten. Deshalb wurden Techniken entwickelt, diesem „Verschnitt“ zu begegnen. Zunächst wurden Netzwerkadressen variabler Länge eingeführt. Dabei wird die Anzahl der für die Netzwerkadresse verwendeten Bits separat angegeben. Meist wird sie mit einem Slash getrennt hinter die Adresse geschrieben. (CIDR-Notation) Z.B. Bezeichnet 192.168.1.34/24 das Gerät 1.34 im Netzwerk 192.168.1, welches eine 24-bittige Netzwerkadresse besitzt (und damit faktisch ein Klasse C-Netz ist). Im RFC 1519 wird die Vergabe von IP-Adressen in dieser Form beschrieben. (vgl. Sikora, 2003 Kap. 5.3)

1.2.2 IPv6

Die Adressknappheit bei IPv4 führte 1995 zur Entwicklung des Nachfolgers IPv6. Dieses nutzt einen Adressraum von 128 Bits, damit stehen 2128 IPv6-Adressen zur Verfügung, d.h. etwa 1,4 Millionen pro Quadratnanometer Erdoberfläche. Neben der Vergrößerung des Adressraums wurden noch weitere Veränderungen eingeführt:

- Der Header wurde verkleinert und vereinfacht. Zusatzfunktionalität wurde in optionale Extension Header ausgelagert. Dadurch sollen Router entlastet werden.
- Automatische Konfiguration von neuen Geräten im Netzwerk. Dadurch sollen Techniken wie DHCP überflüssig werden.
- Die Technik Mobile IP, die es mobilen Geräten ermöglicht, zwischen mehreren Netzen zu wechseln und dabei eine feste IP-Adresse zu behalten. (vgl. Wikipedia „Mobile IP“)
- IPsec wurde Teil des IPv6-Standards, dies soll die Verschlüsselung und Authentifizierung von IP-Paketen ermöglichen.

Bei IPv6 entfällt die Unterteilung des Adressbereiches in Klassen von Netzwerken, es wird die CIDR-Notation verwendet. Außerdem stellen die ersten 64 Bit ein Netzwerkpräfix dar, welches für jedes Netzwerk eindeutig vergeben wird. Die folgenden 64 Bit stellen den Interface Identifier dar. Wird der Interface Identifier beibehalten, kann der Teilnehmer beim Wechseln von einem Netz ins andere weiterhin identifiziert werden. Außerdem kann er mit demselben Interface Identifier zu mehreren Netzen gehören.

Da IPv6-Adressen länger beibehalten werden (können) wird IPv6 dafür kritisiert, die Verfolgung des Verhaltens von Nutzern zu erleichtern. Dagegen wurden die sogenannten Privacy Extensions spezifiziert, die einen regelmäßigen Wechsel des Interface Identifiers ermöglichen. Da im privaten Bereich allerdings oft bereits das Präfix eindeutig ist, fordert der Deutsche IPv6-Rat in seinen Datenschutzleitlinien, dass auch dieses zusammen mit dem Interface Identifier gewechselt wird.

RFC 4291 legt die schriftliche Notation von IPv6-Adressen wie folgt fest: Eine Adresse besteht aus acht Blöcken mit jeweils vier hexadezimalen Ziffern. Führende Nullen dürfen ausgelassen werden. Maximal einmal dürfen (auch mehrere) Blöcke die nur aus Nullen bestehen zu einem: zusammengefasst werden. Die letzten vier Bytes dürfen auch in der Dezimalnotation von IPv4 geschrieben werden, dadurch soll die Einbettung des IPv4-Adressraums erleichtert werden.

IPv6 und IPv4 können gleichzeitig innerhalb derselben Infrastruktur betrieben werden. Es stehen Übersetzungsmechanismen zur Verfügung, die es ausschließlich per IPv4 angebundenen Geräten ermöglichen, mit ausschließlich per IPv6 angebundenen Geräten zu kommunizieren.

IPv6 verbreitet sich nur langsam. Im Juni 2011 befanden sich nur etwa 6000 Präfixe in der globalen IPv6-Routingtabelle und nur etwa 11% der im Internet verfügbaren Autonomen Systeme routeten IPv6. Seit September 2012 vergibt die Deutsche Telekom IPv6-Anschlüsse an Neukunden.

1.2.3 Transmission Control Protocol

Das Transmission Control Protocol (TCP) stellt eine Verbindung zwischen zwei Netzwerkgeräten für einen Datenstrom zur Verfügung. Die wichtigsten Eigenschaften von TCP sind

• Zuverlässige Übertragung: TCP garantiert, dass die zu übertragenden Daten vollständig und fehlerfrei beim Empfänger ankommen. Außerdem wird garantiert, dass die korrekte Reihenfolge rekonstruierbar ist.

- Bidirektionaler Datenstrom: TCP überträgt Daten in beide Richtungen gleichzeitig und unabhängig voneinander.
- Transparenz: Der zu übertragende Datenstrom wird weder verändert noch interpretiert, sondern bitidentisch übertragen.
- Verbindungsorientiert: TCP-Verbindungen besitzen verschiedene Zustände in denen sie sich befinden können und TCP regelt die Zustandsverwaltung.

Es ist wichtig zu wissen, dass TCP keine Sicherheitsmaßnahmen implementiert und gezielte Störungen daher mit anderen Mitteln verhindert werden müssen.

1.3 Verbindungen

TCP ist ein verbindungsorientiertes Protokoll. Es kennt drei Zustände: Verbindungsaufbau, Übertragung und Verbindungsabbau. Der Verbindungsaufbau läuft so ab, dass der eine Partner ein Paket mit gesetztem SYN-Flag sendet, der andere Partner antwortet mit gesetztem SYN- und gesetztem ACK-Flag, was der erste Partner mit gesetztem ACK-Flag quittiert. Die Übertragung wird im Weiteren mit dem DATA-Flag gekennzeichnet.

1.4 Portnummern

Eine Portnummer ist eine 16 Bit lange Zahl, welche beim Verbindungsaufbau festgelegt wird und für die gesamte Verbindung Gültigkeit hat. Anhang der Portnummer kann die Anwendung mit der Verbindung aufgenommen werden soll identifiziert werden. Eine Portnummer kann pro Gerät immer nur von einer Anwendung benutzt werden. Es werden drei Bereiche von Portnummern unterschieden: Die ersten 1024 Ports außer Port 0 (welcher nicht verwendet wird) werden als Well-Known-Ports bezeichnet und werden von der IANA bestimmten Anwendungen zugeordnet. Sie sollen nicht für andere Anwendungen verwendet werden. Die Ports 1024 – 4999 werden Benutzerports genannt und werden üblicherweise von verschiedenen Anwendungen verwendet ohne dass diese sich dafür registriert hätten. Die restlichen Ports (5000-65535) werden als benutzerdefinierte Ports bezeichnet und können frei verwendet werden. Einige wichtige Portnummern sind in Tabelle 2: Wichtige Portnummern aufgeführt.

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 2: Wichtige Portnummern

1.5 User Datagram Protocol

Das User Datagram Protocol (UDP) ist ein weiteres Protokoll, welches einen Datenstrom zwischen zwei Endgeräten überträgt. Anders als TCP garantiert es aber nicht die Ankunft, noch die Reihenfolge der Ankunft der Packete. Es arbeitet ebenfalls transparent, stellt aber nur einen unidirektionalen Datenstrom bereit.

Durch diese Einschränkungen kommt UDP mit deutlich weniger Overhead aus. Es wird verwendet wenn einige Packetverluste akzeptiert werden können oder bei simplen Abfrage-Protokollen wie DNS. Z.B. nützt es Internet-Telefonie nichts, wenn ein verlorenes Packet nachträglich eingespielt wird.

1.6 Domain Name System

Das Domain Name System (DNS) ist ein System das zu einem Domainnamen eine oder mehrere IP-Adressen findet. Es ist verteilt und in zweifacher Hinsicht hierarchisch aufgebaut. Erstens ist das DNS in Zonen aufgeteilt, welche eine hierarchische Struktur besitzen und zweitens sind auch die Nameserver hierarchisch organisiert.

1.6.1 Aufbau des DNS

Ein Domainname wie z.B. www.htw-aalen.de besteht aus mehreren Domains, welche von rechts nach links durch Punkte getrennt angegeben wurden. de ist die Top-Level-Domain, htw-aalen die Second-Level-Domain und www die Third-Level-Domain. Dabei werden die Top-Level-Domains von der Organisation ICANN vergeben, die Second-Level-Domains von nationalen Registraren (für Deutschland die Denic) und die Third-Level-Domains von den Inhabern der jeweiligen Second-Level-Domain.

1.6.2 Namensauflösung

Die IP-Adresse zu einer Domain wird bei den so genannten Nameservern abgefragt. Soll die Domain http://www.htw-aalen.de aufgelöst werden so muss zunächst die IP-Adresse wenigstens ein Root-Nameserver bekannt sein. Dort kann die Adresse des für die TLD .die zuständigen Nameservers abgefragt werden. Bei dem so erhaltenen Nameserver wird dann der für htw-aalen zuständige Nameserver abgefragt. Dieser wiederum liefert die IP-Adresse von www.htw-aalen.de. Dabei können aber auch eigentlich unzuständige Nameserver Anfragen beantworten, da diese einen Cache implementieren.

Es ist auch möglich zu einer gegebenen IP-Adresse die zugehörige Domain zu finden. Dazu liest man die IP-Adresse rückwärts und hängt die Domain in-addr.arpa an. Bei der so entstandenen Domain kann nun die zur IP-Adresse gehörende Domain abgefragt werden.

Um zur IP-Adresse 12.34.56.78 also die Domain zu erfahren, muss bei 78.56.34.12.in-addr.arpa abgefragt werden.

1.7 Sicherheit

Da DNS keine Sicherheitsmaßnahmen vorsieht ist es einem Angreifer möglich, auf eine DNS-Anfrage auch selbst zu antworten. In diesem Fall wird meist die erste Antwort verwendet. Dadurch ist es möglich, einem Netzwerkteilnehmer eine falsche IP-Adresse unterzuschieben, was den Angreifer in eine Man-in-the-Middle-Position bringt. Es ist damit auch möglich, den Benutzer auf eine gefälschte Website zu locken und dort etwa Passwörter abzufangen.

1.7.1 Transport Layer Security

Transport Layer Security (TLS) ist ein Protokoll, das auf der Transportschicht angesiedelt ist und die Inhalte darüberlegender Schichten sicher überträgt und Nachfolger von SSL. Es kann somit die Inhalte beliebiger darüberlegender Protokolle schützen. Unterstützt wird die Verschlüsselung der Kommunikation, die Integrität der Nachrichten und die Authentifizierung beider Kommunikationspartner. Dazu wird asymmetrische Kryptografie für den Schlüsselaustausch, symmetrische Kryptografie für die Verschlüsselung der Nachrichten und Message Authentication Codes für die Sicherstellung der Integrität verwendet.

[...]

Fin de l'extrait de 31 pages

Résumé des informations

Titre
Client-Server-Socket Programmierung: Unterstützung in unterschiedlichen Programmiersprachen
Sous-titre
Mit Fallbeispielen
Université
University of Applied Sciences Aalen
Cours
Rechnernetze
Note
2.0
Auteurs
Année
2013
Pages
31
N° de catalogue
V231487
ISBN (ebook)
9783656484547
ISBN (Livre)
9783656484585
Taille d'un fichier
1114 KB
Langue
allemand
Mots clés
client-server-socket, programmierung, unterstützung, programmiersprachen, fallbeispielen
Citation du texte
Daniel Szameitat (Auteur)Martin Haug (Auteur)Christian Bosch (Auteur), 2013, Client-Server-Socket Programmierung: Unterstützung in unterschiedlichen Programmiersprachen, Munich, GRIN Verlag, https://www.grin.com/document/231487

Commentaires

  • Pas encore de commentaires.
Lire l'ebook
Titre: Client-Server-Socket Programmierung: Unterstützung in unterschiedlichen Programmiersprachen



Télécharger textes

Votre devoir / mémoire:

- Publication en tant qu'eBook et livre
- Honoraires élevés sur les ventes
- Pour vous complètement gratuit - avec ISBN
- Cela dure que 5 minutes
- Chaque œuvre trouve des lecteurs

Devenir un auteur