HTTP-Request liefert keine Antwort

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Lolek
Beiträge: 4
Registriert: Mi Dez 02, 2020 5:55 pm

HTTP-Request liefert keine Antwort

Beitrag von Lolek » Mi Dez 02, 2020 6:32 pm

Hallo Leuts,

ich versucht gerade autodidaktisch c zu lernen. Ich habe schon einige Versuche gemacht, habe aber jetzt ein Problem mit dem ich nicht weiter komme.

Das Ziel ist es eine Textdatei über http zu lesen und den darin gespeicherten Text auszuwerten. Es ist mir bewusst, dass es für einen Anfänger etwas vermessen ist sich an Sockets zu versuchen. :shock: Der Socket ist aber ein notwendiges Übel um an die Datei zu kommen. Ich habe mir aus dem Netz ein Code- Beispiel geladen und es angepasst.

Ich kann den Code unter Linux compilieren und auch ausführen. Mit folgendem Aufruf kann ich eine CSS Datei von meiner Fritzbox laden und im Terminal ausgeben.

Code: Alles auswählen

prog fritz.box /css/rd/login.css
Die Textdatei die ich laden will befindet sich auf einem Raspi mit openwrt und dem Webserver uhttpd.
Ich habe versucht die Textdatei mit folgendem Aufruf zu lesen.

Code: Alles auswählen

prog raspi.im.lan /bla/bla.txt
Nach dem Aufruf bleibt der Terminal schwarz und das Programm wird nach einer gewissen Zeit ohne Fehler beendet.

Könnte mir jemand bei dem Problem weiter helfen? Vorab schon mal danke für alle Antworten.

Hier ist der Code.

Code: Alles auswählen

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
/* Windows-System */
#ifdef _WIN32
#include <winsock.h>
#include <io.h>
/* Unix-System */
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
#define HTTP_PORT 80

int main(int argc, char **argv){
	int sock;
	struct sockaddr_in host_addr;
	struct hostent *hostinfo;
	char *host, *file;
	char command[1024];
	char buf[1024];
	unsigned int bytes_sent, bytes_recv;
	/* Ist der Aufruf korrekt? */
	if (argc != 3) {
		fprintf (stderr, "Aufruf: httprecv host file\n");
		exit (EXIT_FAILURE);
	}
	host = argv[1];
	file  = argv[2];
	/* ggf. Winsock initialisieren */
	#ifdef _WIN32W
	SADATA wsaData;
	if (WSAStartup (MAKEWORD(1, 1), &wsaData) != 0) {
		fprintf (stderr, "WSAStartup(): Kann Winsock nicht initialisieren.\n");
		exit (EXIT_FAILURE);
	}
	#endif
	/* Socket erzeugen */
	sock = socket (AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		perror ("socket()");
		exit (EXIT_FAILURE);
	}
	/* Adresse des Servers festlegen */
	memset( &host_addr, 0, sizeof (host_addr));
	host_addr.sin_family = AF_INET;
	host_addr.sin_port = htons (HTTP_PORT);
	host_addr.sin_addr.s_addr = inet_addr (host);
	if (host_addr.sin_addr.s_addr == INADDR_NONE) {
		/* Server wurde nicht mit IP sondern mit dem Namen angegeben */
		hostinfo = gethostbyname (host);
		if (hostinfo == NULL) {
			perror ("gethostbyname()");
			exit (EXIT_FAILURE);
		}
		memcpy((char*) &host_addr.sin_addr.s_addr, hostinfo->h_addr, hostinfo->h_length);
	}
	/* Verbindung aufbauen */
	if (connect(sock, (struct sockaddr *) &host_addr, sizeof(struct sockaddr)) == -1) {
		perror ("connect()");
		exit (EXIT_FAILURE);
	}
	/* HTTP-GET-Befehl erzeugen */
	sprintf (command, "GET %s HTTP/1.0\nHost: %s\n\n", file, host);
	/* Befehl senden */
	bytes_sent = send (sock, command, strlen (command), 0);
	if (bytes_sent == -1) {
		perror ("send()");
		exit (EXIT_FAILURE);
	}
	// Antwort des Servers empfangen und ausgeben */
	while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) {
		write (1, buf, bytes_recv);
	}
	if (bytes_recv == -1) {
		perror ("recv()");
		exit (EXIT_FAILURE);
	}printf ("\n");
	#ifdef _WIN32
	closesocket(sock);
	WSACleanup();
	#else
	close(sock);
	#endif
	return 0;
}

EDIT nufan: Titel (war "Anfängerproblem")

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Anfängerproblem

Beitrag von Xin » Mi Dez 02, 2020 6:38 pm

Bevor ich mir das Programm genauer angucke... auf welchem System compilierst und testest Du denn überhaupt?

Und wo kommt das Programm her?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Anfängerproblem

Beitrag von nufan » Mi Dez 02, 2020 7:03 pm

Der HTTP-Standard (https://tools.ietf.org/html/rfc2616) erwartet sich "\r\n" zwischen den Zeilen, nicht bloß "\n". Möglicherweise ist uhttpd in diesem Fall strenger als die Fritzbox und erkennt deinen Request nicht?

Ansonsten würde ich empfehlen im Hintergrund den Netzwerkverkehr mit z.B. Wireshark mitzuschneiden und am Server einen Blick in die Access-Logs zu werfen.

Lolek
Beiträge: 4
Registriert: Mi Dez 02, 2020 5:55 pm

Re: Anfängerproblem

Beitrag von Lolek » Mi Dez 02, 2020 7:56 pm

Ups, das ging ja schnell. Super!

Vielen Dank für die Antworten.

@Xin: Ich hatte oben im Text geschrieben, dass ich das Programm unter Linux compiliert habe. Ich habe es mit gcc im Terminal übersetzt (gcc prog.c -o prog). Den Code habe ich aus einem Tutorial über Socket Programmierung. Das was ich hier abgebildet habe ist der original Code, den ich mit der Fritzbox, wie oben beschrieben, getestet habe. Ich habe mit dem Code in einem Testprogramm etwas rumgespielt, um einigermassen zu verstehen was eigentlich abläuft. Ist aber noch ziemlich kryptisch für mich. :roll:

@ nufan: Danke für den Tipp mit dem RFC. Ich werde das gleich testen.

Lolek
Beiträge: 4
Registriert: Mi Dez 02, 2020 5:55 pm

Re: Anfängerproblem

Beitrag von Lolek » Mi Dez 02, 2020 8:17 pm

Hurra!
so hat es funktioniert.

Code: Alles auswählen

sprintf (command, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", file, host);
Vielen Dank für die Unterstützung und schöne Weihnachten.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Anfängerproblem

Beitrag von Xin » Mi Dez 02, 2020 8:35 pm

Lolek hat geschrieben:
Mi Dez 02, 2020 7:56 pm
@Xin: Ich hatte oben im Text geschrieben, dass ich das Programm unter Linux compiliert habe.
Okay... das habe ich überlesen.

Schön, dass es jetzt funktioniert. :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Lolek
Beiträge: 4
Registriert: Mi Dez 02, 2020 5:55 pm

Re: Anfängerproblem

Beitrag von Lolek » Mi Dez 02, 2020 8:42 pm

Jo, danke nochmal.

Antworten