Was ist das hier?

  • Eine Plattform von Flensburger Studenten für Flensburger Studenten
  • Ein Wiki zum Sammeln von Wissen
  • Ein Forum zum Austausch
  • Eine Wissensdatenbank zum Informatikstudium:
    • Programmieren in C, C#, PHP, Javascript, HTML, CSS
    • Datenbanken und Abfragen mit SQL
    • 2D / 3D - Gestaltung
    • Mathe, Physik, Gerätetechnik, RoBs
    • Audio- / Videotechnik
    • ...und vieles mehr

Anmelden

Warum registrieren?

Weil besser als gut!

 

Lösung Übung 2

Das meisste ist schon da

Ausgehend von der ersten Übung müssen wir nur ein paar Zeilen Code ändern. Da wir nun die ServerIP durch Eingabe einer Ip oder eines Hostnames in die Kommandozeile erhalten sollen, müssen wir die in netdb.h vorliegende function gethostbyname() benutzen.

Also müssen wir nur im Client (udpEchoTest.cpp) das initialisieren der Variablen ändern.

Alte Version

C++
 
const unsigned long SERVER_IP = inet_addr(argv[1]);
const int SERVER_PORT = atoi(argv[2]);
(..)
 
//Variablen Initialisieren
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = SERVER_IP;
 

Für die Modifizierung brauchen wir folgende Codestücke:

1.) #include <netdb.h>
2.) hostent* host_ptr;
3.) host_ptr = gethostbyname(argv[1]);
4.) server_addr.sin_addr = *((in_addr*)(host_ptr->h_addr));

und zusätzlich eine neue Exception die geworfen wird, wenn in gethostbyname() ein Fehler auftritt und das Ergebnis (host_ptr) gleich NULL ist.

1. Der include ist notwendig um gehostbyname() verwenden zu können.

2. Das Ergebnis von gethostbyname() ist ein Pointer auf ein in_addr-Structure allerdings vom Typ hostent*, wir speichern das Ergebnis in host_ptr.

3. Auflösung des Hostnames aus argv[1], eine IP-Adresse kann die Function auch annehmen. Tritt ein Fehler auf, wird ein NULL-Pointer übergeben.

4. Hier kommt die erst wirkliche Änderung der Initialisierung aus Übung 1.

Statt der sin_addr.s_addr die IP zuzuweisen:

server_addr.sin_addr.s_addr = SERVER_IP;

können wir direkt an die sin_addr das Structure aus gethostbynamezuweisen, da der Typ aber hostent* ist, müssen wir dies Typecasten:

server_addr.sin_addr = *((in_addr*)(host_ptr->h_addr));

5. Eine entsprechende Exception muss erzeugt werden.

So sieht eine entsprechende Lösung für die zweite NWK-Labor-Übung wie folgt aus:

C++
 
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
 
using namespace std;
 
class RECVError{};
class BINDError{};
class SENDError{};
class SOCKETError{};
class HOSTError{};
class AufrufFehler{};
 
int main(int argc, char* argv[])
{
	try
	{
		if(argc != 3)
			throw AufrufFehler();
 
		const int SERVER_PORT = atoi(argv[2]);
 
		sockaddr_in server_addr; //Server Adresse
		hostent* host_ptr;
		int sfd;
		int binding;
		int sending;
		int recv;
		char buf_ptr[256];
		char nachricht[256] = "TEST TEST"; //char variable für message
 
		//Variablen Initialisieren
		host_ptr = gethostbyname(argv[1]);
		if(host_ptr == NULL)
			throw HOSTError();
		server_addr.sin_family = AF_INET;
		server_addr.sin_port = htons(SERVER_PORT);
		server_addr.sin_addr = *((in_addr*)(host_ptr->h_addr));
 
		/* Ab jetzt kann der sfd und alles weitere wie in Aufgabe 2 erzeugt werden,
		 * ein entsprechender catch(HOSTError)
		 * ist noch einzubauen.
		*/
	}
}
 

Lösungsansatz aus 2010

Hier ist die Lösung zu Aufgabe 2 in NWK. Es ist jetzt möglich den Hostname oder eine IP anzugeben. Wird ein ungültiger Hostname oder eine ungültige IP kommt eine Exception.

CPP
 
// echo_client.cpp //
 
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h> 
 
using namespace std;
 
class HILFE{};
class SFD{};
class REC{};
class SEND{};
class GETHOSTNAME{};
 
int main(int argc, char* const argv[])
{
        // Initialisierung der Variablen
        unsigned long ip;                         // enthaellt spaeter die ip 
        int port;                                 // enthaellt spaeter den Port
        int sfd;                                  // Socket Descriptor: Fehlercode fuer socket(...)
        int send;                                 // Fehlercode fuer sendto(...)
        int rec;                                  // Fehlercode fuer recvfrom(....)
 
 
        char nachricht[] = "Hallo Herr Exner";    // die zusendende Nachricht
        char buffer[256];                         // die empfangende Nachricht
 
	struct hostent *hent;			  // Hostname
	sockaddr_in server_addr;                  // Server Daten
 
 
        try
        {
                // wirf eine Exception wenn nicht IP und Port angegeben werden
                if(argc != 3)
                        throw HILFE();
 
                // Ausgabe der Parameter
                for(int c = 0; c < argc; c++)
                {
                        cout << "argv[" <<  c << "] = " << argv[c] << endl;
                }
 
		// Port Ermittlung
		port = atoi(argv[2]);
 
		server_addr.sin_family = AF_INET;
		server_addr.sin_port = htons(port);
 
		hent = gethostbyname(argv[1]);      // ermitteln der IP des Hostnames
 
		// wenn keine gültige IP / Hostname verwendet wurde
		if (hent == NULL)
                        throw GETHOSTNAME();
 
	        server_addr.sin_addr  =	*(struct in_addr*) hent->h_addr;
 
                // Socket erstellen
                sfd = socket(AF_INET, SOCK_DGRAM, 0);
                if (sfd < 0)
                        throw SFD();
 
                // verschicken der Nachricht
                send = sendto(sfd, nachricht, sizeof(nachricht), 0,(sockaddr*)&server_addr, (socklen_t)sizeof(server_addr));
                if (send < 0)
                        throw SEND();
 
                // Antwort empfangen
                socklen_t  size = sizeof(server_addr);
                rec = recvfrom(sfd, buffer, sizeof(buffer), 0,(sockaddr*)&server_addr, &size);
                if (rec < 0)
                        throw REC();
 
                // Antwort ausgeben
                cout << "IP des Servers:   " << inet_ntoa(server_addr.sin_addr) << endl;
                cout << "Antwort erhalten: " << buffer << endl;
 
                // Socket schliessen
                close(sfd);
        }
 
        // Ausgabe bei fehlerhafter Eingabe
        catch(HILFE)
        {
                cout << "n usage: " << argv[0] << " IP PORT n";
        }
	catch(GETHOSTNAME)
	{
		cout << "error beim ermitteln der IP vom DNS NAMENn";
	}
        catch(SFD)
        {
                cout << "error beim Socketn";
        }
 
        catch(SEND)
        {
                cout << "error beim Empfangen der Nachrichtn";
        }
 
        catch(REC)
        {
                cout << "error beim Senden der Nachrichtn";
        }
 
        // Ausgabe bei sonstigen Fehlern
        catch(...)
        {
                cout << "n error! n";
        }
 
        return 0;
 
}
 
 
| Mehr

Zahlen & Daten

  • 4840 Seitenaufrufe
  • 739 Tage alt
  • 17 Versionen
  • Letzte Änderung: 11.05.2011 um 13:09 Uhr

Publish