www.mikrocontroller.net

Forum: PC-Programmierung C/C++ Socket Programmierung


Autor: Andreas Wilhelm (avedo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend!

Ich beschäftige mich momentan mit Socket Programmierung in C. Dazu 
arbeite ich schrittweise die Seite 
http://www.zotteljedi.de/socket-tipps/index.html durch. Dort habe ich 
auch einen kleinen PortScanner in C gefunden, der mir recht gut gefallen 
hat, und so habe ich mir vorgenommen diesen in C++ nach zu 
programmieren.

Zu diesem Zweck habe ich eine Klasse TcpSocket geschrieben, die mir die 
Verbindung zu einem Server erleichtern soll. Eine Klasse SocketTest in 
der Datei Main.cpp implementiert darauf basierend den eigentlichen 
PortScanner.

Das Projekt kompiliert, liefert jedoch den Fehler, dass keine Verbindung 
aufgebaut werden kann. Der Fehler muss also in der Methode
bool TcpSocket::connectTo(std::string host, int port) throw(TcpSocketException);

liegen. In den betreffenden Zeilen
  if( connect(this->sock, (struct sockaddr*) &addr, sizeof(addr)) == -1 ) {
    // ... and handle errors.
      throw TcpSocketException("Failed to connect to " + host + ".");
  }

kann ich leider keinen Fehler finden. Mache ich vielleicht bei der 
Umrechnung der IP bzw. Host-Adresse etwas falsch? Wäre nett, wenn sich 
das jemand anschauen könnte.

Das Projekt habe ich als *.tar.gz angehängt. Bitte nicht über den Namen 
wundern.

Liebe Grüße,

Andreas

Autor: duselbaer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe mir den Beispielcode jetzt nicht angeschaut, würde Dir aber zum 
Thema Socketprogrammierung in C++ die Boost-Libs - insbesondere 
Boost.Asio - ans Herz legen.

Gruss,

RSp

Autor: duselbaer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso, ansonsten setzt die connect-Funktion für gewöhnlich einen 
Errorcode in der Variable errno. Manchmal hilft es, diesen auszuwerten. 
Vielleicht kannst Du da was erkennen.

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
errno (unter Windows WSAGetLastError) auszugeben sollte weiterhelfen, 
den Fehler einzugrenzen.

Autor: Andreas Wilhelm (avedo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Danke für deine Antwort. Werde mir die Boost-Library auf jeden Fall mal 
ansehen.

Der Fehler scheint im übrigen nur dann aufzutauchen, wenn ich eine 
Host-Adresse (URL) entgegen nehme. Kann es sein, dass ich etwas bei der 
Umwandlung falsch mache?

Nachfolgend mal der betreffende Code-Ausschnitt.
  // Check if given host address is an ip.
  if( inet_aton(host.c_str(), &addr.sin_addr) == 0 ) {
    // If not get data by hostname ...
    hostData = gethostbyname(host.c_str());
    
    // Validate host data ...
    if (!hostData) {
      // ... and handle errors.
      throw TcpSocketException("Failed to resolve " + host + ".");
    }
    
    // Finally set host address.
    addr.sin_addr = *(struct in_addr*) hostData->h_addr;
  }
  
  else {
    // If ip was given set host address by ip.
    addr.sin_addr.s_addr = inet_addr(host.c_str());
  }

  // Init address structure.
  addr.sin_port = htons(port);
  addr.sin_family = AF_INET;

  // Establish connection to given ip address and port ...
  if( connect(this->sock, (struct sockaddr*) &addr, sizeof(addr)) == -1 ) {
    // ... and handle errors.
      throw TcpSocketException("Failed to connect to " + host + ".");
  }

  return true;

Liebe Grüße,

Andreas

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Wilhelm schrieb:
> Der Fehler scheint im übrigen nur dann aufzutauchen, wenn ich eine
> Host-Adresse (URL) entgegen nehme.
Eine URL kannst du nicht angeben. "mikrocontroller.net", 
"www.mikrocontroller.net" sollte funktionieren, aber 
"http://mikrocontroller.net" ist zwar eine URL aber kein gültiger 
Hostname!

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Zeile 12:
sock = socket(PF_INET, SOCK_STREAM, 0);
Man soll angeblich korrekt AF_INET schreiben, aber das ist wohl 
praktisch immer egal.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Wilhelm schrieb:

> Der Fehler scheint im übrigen nur dann aufzutauchen, wenn ich eine
> Host-Adresse (URL) entgegen nehme. Kann es sein, dass ich etwas bei der
> Umwandlung falsch mache?


Sein kann alles.
Hast du denn keinen Debugger, mit dem du den Code in Einzelschritten 
durchgehen kannst? Oder eine Ausgabefläche (Monitor, Textfenster) in das 
du Fehlermeldungen samt Parameter bzw. ganz einfache Log-Meldungen ala 
'Now trying to resolve Host-Name' ausgeben kannst und zwar an der Stelle 
bzw. bevor der Fehler gethrowd wird?

Autor: Andreas Wilhelm (avedo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend!

Karl heinz Buchegger schrieb:
> Hast du denn keinen Debugger, mit dem du den Code in Einzelschritten
> durchgehen kannst? Oder eine Ausgabefläche (Monitor, Textfenster) in das
> du Fehlermeldungen samt Parameter bzw. ganz einfache Log-Meldungen ala
> 'Now trying to resolve Host-Name' ausgeben kannst und zwar an der Stelle
> bzw. bevor der Fehler gethrowd wird?

Normalerweise arbeite ich ja mit dem QtCreator. Der hat 
selbstverständlich einen Debugger. Leider bin ich momentan mit meinem 10 
Zoll Netbook auf reisen auf dessen Display leider kein Platz für diese 
IDE ist. Natürlich habe ich versucht mit Log-Meldungen dahinter zu 
kommen, aber irgenetwas ging da schief.

duselbaer schrieb:
> Ich habe mir den Beispielcode jetzt nicht angeschaut, würde Dir aber zum
> Thema Socketprogrammierung in C++ die Boost-Libs - insbesondere
> Boost.Asio - ans Herz legen.

Ich habe mir die entsprechenden Bibliotheken heute mal angeschaut und 
etwas damit rumgespielt. Ich habe nun den PortScanner auf Basis der 
Boost Bibliotheken noch einmal neu geschrieben und stehe nun noch vor 
einem Problem. Ich habe in der Doku keine Möglichkeit gefunden anhand 
eines Ports den Namen des dazugehörigen Services auszugeben. Gibt es 
dafür irgendeine Funktion?

Außerdem ist das Programm momentan noch sehr langsam. Gibt es irgendeine 
Möglichkeit das ganze etwas zu beschleunigen?

Abschließend würde mich noch interessieren, ob man das so programmieren 
kann. Habe schon oft in Java, MatLab, C oder PHP programmiert, jedoch 
recht selten in C++.

Liebe Grüße,

Andreas

PS: Den PortScanner findet ihr im Anhang.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Wilhelm schrieb:
> Ich habe in der Doku keine Möglichkeit gefunden anhand
> eines Ports den Namen des dazugehörigen Services auszugeben. Gibt es
> dafür irgendeine Funktion?

Zumindest unter Unix/Linux steht das in /etc/services, falls dir
nicht eleganteres über den Weg läuft.

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Zumindest unter Unix/Linux steht das in /etc/services, falls dir
> nicht eleganteres über den Weg läuft.
Dabei brauchst du sie aber nicht von Hand parsen, Linux hat dafür 
Funktionen:
http://linux.die.net/man/5/services

Autor: Andreas Wilhelm (avedo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend!

Niklas Gürtler schrieb:
> Klaus Wachtler schrieb:
> Dabei brauchst du sie aber nicht von Hand parsen, Linux hat dafür
> Funktionen:
> http://linux.die.net/man/5/services

Wenn ich das richtig sehe, habe ich genau das in meiner ersten Version 
gemacht. Wieso sollte man dann die Boost Bibliotheken verwenden. Welchen 
wirklich Vorteil bieten sie? Ich habe mich bisher nur darüber geärgert, 
dass man einen Port nur als String übergeben kann. Das verschließt sich 
mir jeglicher Logik.

Liebe Grüße,

Andreas

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Wilhelm schrieb:
> Wieso sollte man dann die Boost Bibliotheken verwenden.

Falls das eine Frage ist: weil das Programm dadurch auch unter
Windows oder sonstwo übersetzbar ist, wo es die boost-Lib gibt..

Autor: Andreas Wilhelm (avedo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Falls das eine Frage ist: weil das Programm dadurch auch unter
> Windows oder sonstwo übersetzbar ist, wo es die boost-Lib gibt..

Das gilt aber nicht mehr, sollte ich die Sockets, wie oben 
vorgeschlagen, abfragen.

Liebe Grüße,

Andreas

Autor: Bob der Baumeister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Wilhelm schrieb:
> Das gilt aber nicht mehr, sollte ich die Sockets, wie oben
> vorgeschlagen, abfragen.

Was wiederrum der Grund ist, warum dir die Boost-Lib vorgeschlagen 
wurde.

Wenn dir Boost nicht zusagt, aber die QT: Da gibts doch auch schöne 
QSocket Klassen usw. Die lassen sich auch ohne GUI verwenden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.