Forum: PC-Programmierung Winsocket Problem beim aufrufen einer WEB Seite


von Oliver (Gast)


Lesenswert?

Hallo,

ich wollte mit diesem kleinen Programm eine Webseite einlesen.
Das Programm stammt nicht von mir aber es würde genau das machen was ich 
haben will, wenn es den gehen würde.
Weiter am Ende
1
/***************************************************************************
2
Name:          getpage.c
3
Autor:         www.c-worker.ch
4
Beschreibung:  Zeigt die Antwort des Webservers auf eine bestimmte URL an
5
               oder lädt wahlweise die Site in eine Datei herunter.
6
Return Code:   0 = ok,  >0 oder <0 = Fehler
7
8
----------------------------------------------------------------------------
9
Aus RFC 1945, HTTP/1.0:
10
Full-Response  = Status-Line
11
                 *( General-Header
12
                  | Response-Header
13
                  | Entity-Header )
14
                 CRLF   (ich gehe in diesem Code davon aus es handelt sich um \x0D\x0A\x0D\x0A)
15
                 [ Entity-Body ]
16
17
****************************************************************************/
18
19
#include <windows.h>
20
#include <winsock2.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
24
void perr_exit(char* msg, int ret_code)
25
{
26
  printf("%s, Error: ",msg);
27
  printf("%d\n",ret_code);
28
  exit(ret_code);
29
}
30
31
void usage(char* prgname)
32
{
33
  printf("\nUsage:\t");
34
  printf("%s <URL> [<File>]\n",prgname);
35
  printf("\tURL:  Website URL\n");
36
  printf("\tFile: Optional File to store the Website\n");
37
  exit(0);
38
}
39
40
int main(int argc, char** argv)
41
{
42
  char* url;
43
  char* site;
44
  char* host;
45
  char  buf[1024];
46
  char  send_buf[256];
47
  char  recv_buf[256];
48
  long  rc;
49
  FILE* target_file;
50
  char  uses_file=0;
51
  char* write_ptr;
52
  SOCKET s;
53
  SOCKADDR_IN addr;
54
  WSADATA wsa;
55
  HOSTENT* hent;
56
57
  if(WSAStartup(MAKEWORD(2,0),&wsa))
58
    perr_exit("WSAStartup failed",WSAGetLastError());
59
60
  addr.sin_family=AF_INET;
61
  addr.sin_port=htons(80);
62
63
  if(argc<2)
64
  {
65
    printf("\nURL: ");
66
    scanf("%s",buf);
67
    url=buf;
68
  }
69
  else
70
  {
71
    if(strcmp(argv[1],"/?")==0 ||
72
    strcmp(argv[1],"/help")==0 ||
73
    strcmp(argv[1],"/h")==0 ||
74
    strcmp(argv[1],"--help")==0 ||
75
    strcmp(argv[1],"-h")==0)
76
      usage(argv[0]);
77
78
    url=argv[1];
79
  }
80
  if(argc>2)
81
  {
82
    if(!(target_file=fopen(argv[2],"w")))
83
    {
84
      printf("Cannot open File ");
85
      perr_exit(argv[2],GetLastError());
86
    }
87
    uses_file=1;
88
  }
89
90
  if(strncmp("http://",url,7)==0)
91
    host=url+7;
92
  else
93
    host=url;
94
95
  if((site=strchr(host,'/'))!=0)
96
    *site++='\0';
97
  else
98
    site=host+strlen(host); /* \0 */
99
100
  printf("Host: %s\n",host);
101
  printf("Site: %s\n",site);
102
  printf("Connecting....\n");
103
104
  if((addr.sin_addr.s_addr=inet_addr(host))==INADDR_NONE)
105
  {
106
    if(!(hent=gethostbyname(host)))
107
      perr_exit("Cannot resolve Host",WSAGetLastError());
108
109
    strncpy((char*)&addr.sin_addr.s_addr,hent->h_addr,4);
110
111
    if(addr.sin_addr.s_addr==INADDR_NONE)
112
      perr_exit("Cannot resolve Host",WSAGetLastError());
113
  }
114
115
  if((s=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
116
    perr_exit("Cannot create Socket",WSAGetLastError());
117
118
  if( connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)))
119
    perr_exit("Cannot connect",WSAGetLastError());
120
121
  printf("Connected to %s...\n",host);
122
123
124
  sprintf(send_buf,"GET /%s HTTP/1.0\r\n\r\n",site);
125
126
//  sprintf(send_buf,"GET /%s HTTP/1.0\nUser-Agent:www.google.com\n\n",site);
127
128
  if((send(s,send_buf,strlen(send_buf),0))<strlen(send_buf))
129
    perr_exit("Cannot send Data",WSAGetLastError());
130
131
  if(uses_file)
132
    printf("Downloading Page to File %s...",argv[2]);
133
  else
134
    printf("----Result----\n");
135
136
  while((rc=recv(s,recv_buf,255,0))>0)
137
  {
138
    recv_buf[rc]='\0';
139
    if(uses_file)
140
    {
141
      if(uses_file==1)
142
      {
143
        /* web server info nicht in Datei speichern */
144
        if((write_ptr=strstr(recv_buf,"\x0D\x0A\x0D\x0A"))>0)
145
        {
146
          uses_file=2;
147
          write_ptr+=4;
148
        }
149
      }
150
      else
151
        write_ptr=recv_buf;
152
      if(uses_file==2)
153
      {
154
        if( fwrite(write_ptr,1, rc-(write_ptr-recv_buf), target_file)<rc-(write_ptr-recv_buf))
155
          fclose(target_file);
156
      }
157
    }
158
    else /* uses_file */
159
      printf("%s",recv_buf);
160
  }
161
162
  printf("\nDONE!");
163
  if(uses_file)
164
    fclose(target_file);
165
  closesocket(s);
166
  return 0;
167
}


Das einlesen der Web Seite Funktioniert aber leider nicht.
Der Server (STRATO) meldet:
1
<H1 ALIGN="CENTER">
2
    Bitte benutzen sie nicht die IP Adresse des Servers, sondern immer
3
    www.&lt;Wunschname&gt;.de !!
4
</H1>

Jetzt stellt sich die Frage was muss ich Ändern damit der Strato Server 
mir den Inhalt meiner Seite liefert?

Alles suchen und lesen hat mich bis jetzt nicht weiter gebracht.

Viele Grüsse,
Oliver

: Bearbeitet durch User
von DirkB (Gast)


Lesenswert?

Wie rufst du denn das Programm auf?

von Oliver (Gast)


Lesenswert?

Da das ganze ein "DOS" Programm ist habe ich eine Batch datei.

getip.exe www.test.de/test/hallo.php

von DirkB (Gast)


Lesenswert?

Dir fehlt der host: Eintrag beim GET wie bei 
http://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Funktionsweise
Probier mal:
1
sprintf(send_buf,"GET /%s HTTP/1.1\r\nhost: %s\r\n", site, host);

von Oliver (Gast)


Lesenswert?

Jetzt bleibt die Anfrage hängen.

von DirkB (Gast)


Lesenswert?

Ich weiß nicht ob es zwingend ist, aber schreib mal das Host: mit einem 
großen H
1
sprintf(send_buf,"GET /%s HTTP/1.1\r\nHost: %s\r\n", site, host);

von Oliver (Gast)


Lesenswert?

Das hatte ich schon gemacht. Ist garantiert erforderlich aber hat das 
selbe Ergebnis.

Du hast HTTP/1.1 drin. Im Original File ist 1.0.

Wenn ich im Original File das auf 1.1 ändere bekomme ich eine 
Fehlermeldung:

HTTP/1.1  400 Bad Request

von Oliver (Gast)


Lesenswert?

Oh man ist das ein Mist.

Wie soll man darauf kommen?

sprintf(send_buf,"GET /%s HTTP/1.1\r\nhost: %s\r\n\r\n", site, host);

Man muss 2 mal \r\n am Ende senden.

Dann ist es auch egal ob 1.0 oder 1.1.

von obscurity (Gast)


Lesenswert?

Oliver schrieb:
> Wie soll man darauf kommen?
>
> sprintf(send_buf,"GET /%s HTTP/1.1\r\nhost: %s\r\n\r\n", site, host);

Nach dem HTML-Header Bereich im Request kommen nun mal 2x \r\n. Das war 
schon immer so. Das was nach den 2 mal \r\n kommt sind die Post-Daten, 
falls vorhanden. Also bitte nicht Aufregen, RFCs lesen.

von Oliver (Gast)


Lesenswert?

Es ist ja schön das Du das gewusst hast, nur wo warst Du gestern?

Das ich mich damit nicht so auskenne, hat doch meine Frage schon 
gezeigt.
Ich habe einiges dazu gestern gelesen, aber das ich das alles übersehen 
hatte, zeigt halt auch das man manchmal blind ist.
Wenn man dann hier mal nicht die Standard Floskel "lesen" oder "gib mal 
alles her" erhält sondern richtige Tipps dann bin ich darüber sehr 
erfreut.

Und deshalb noch mal Danke.

von Sven P. (Gast)


Lesenswert?

Kennst du wget und curl?

Oder muss es unbedingt selbst (neu) erfunden sein?

von Oliver (Gast)


Lesenswert?

Kenne ich inzwischen, aber den Code den ich gleich als erstes gefunden 
hatte war am einfachsten zu benutzen.
Gut wenn man mal von dem fehlenden Host Eintrag absieht.

Das es meistens schon was anders gibt ist halt so und so wird es oft 
sein.

von Sven P. (Gast)


Lesenswert?

Oliver schrieb:
> Kenne ich inzwischen, aber den Code den ich gleich als erstes gefunden
> hatte war am einfachsten zu benutzen.

Er ist aber unvollständig (siehst du ja, und es fehlen noch viele andere 
Dinge, die man zum 'runterladen' braucht) und plattformabhängig...

von Oliver (Gast)


Lesenswert?

Für die Plattformunabhängigkeit habe ich das ganze auch als Pythonscript 
nur ich wollte unter Windows halt was haben was ohne Python läuft.

Das Programm kann genau das was ich brauche, das kann sogar schon zu 
viel.

von Udo S. (urschmitt)


Lesenswert?

Oliver schrieb:
> ich wollte mit diesem kleinen Programm eine Webseite einlesen.
> Das Programm stammt nicht von mir aber es würde genau das machen was ich
> haben will, wenn es den gehen würde.

Die neue Art des Programmierens?
:-((

von Dirk (Gast)


Lesenswert?

Und? Wer macht das nicht so?

Wenn ich nicht fit bin in einem Thema und schnell eine Lösung brauche, 
suche ich wie jeder andere auch, in WEB nach passenden Code.

Dirk

von Oliver (Gast)


Lesenswert?

Die neue Art des Programmierens? Klar was sonst!
Kopieren und abschauen bis der Arzt kommt.

Mir ist hier doch auch schon vorgeworfen worden das ich keine LIB nehme.

Mal im ernst, manchmal macht es halt keinen Sinn alles nochmal selber zu 
schreiben. Entweder man nimmt eine fertige LIB oder einen fertigen Code.

So gesehen hast Du recht. Kopieren ist eine Art Programmieren.

Oliver

von Uli (Gast)


Lesenswert?

Hat jemand so ein Programm was unter Linux läuft?

Ich könnte so ein Programm gut gebrauchen.
Bin aber nicht wirklich ein guter Programmierer, bin mehr ein Nutzer.
Für einen Anwendungsfall muss ich mehrfach am Tag eine PHP Seite 
aufrufen
und dabei ein paar Parameter übergeben.

Uli

von Peter II (Gast)


Lesenswert?

Uli schrieb:
> Hat jemand so ein Programm was unter Linux läuft?

unter Linux kann man einfach wget nehmen. (was es aber auch für Windows 
gibt)

von Uli (Gast)


Lesenswert?

Habe ich gerade von Windows aus getestet und es geht soweit.

Nur ich will keine Seite laden sondern nur Daten dahin senden.
Maximal den Inhalt in der Shell ausgeben.
Wobei bei mir nur ein "OK" oder ein "ERROR" kommt.

Ich finde finde in der Doku nichts um den Download zu verhindern, 
übersehe ich was?

Das überschreiben würde auch noch gehen, nur nicht das immer wieder 
anlegen von der Datei. Das müllt mir den Rechner nur zu.

von bluppdidupp (Gast)


Lesenswert?

Du könntest z.B. mit
--output-document=HierEinDateiPfad
die Antwort immer in die gleiche Datei schreiben lassen
--delete-after
sieht auch interessant aus.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.