Forum: PC-Programmierung C: Einfacher Webserver funktioniert nicht


von Max H. (hartl192)


Angehängte Dateien:

Lesenswert?

Ich bin gerade dabei ein bisschen mit HTTP zu experimentieren und habe 
dabei ein Tut gefunden wie man einen ganz einfachen HTTP Server in C# 
schreibt:
https://www.youtube.com/watch?v=GyuUtAqWVPU
Der Code hat auch funktioniert. Da ich eigentlich nicht in C# 
programmiere wollte ich es in C umschreiben. Ich habe das C# Programm 
erst auf das notwendigste gekürzt um einfach nur eine leere Website 
anzuzeigen:
1
static void Main(string[] args)
2
{
3
  TcpListener listener = new TcpListener(8080);
4
  listener.Start();
5
6
  while(true)
7
  {
8
    Console.WriteLine("Wait for a connection");
9
    TcpClient client = listener.AcceptTcpClient();
10
    StreamReader sr = new StreamReader(client.GetStream());
11
    StreamWriter sw = new StreamWriter(client.GetStream());
12
13
    string request = sr.ReadLine();
14
    Console.WriteLine(request);
15
16
    sw.WriteLine("HTTP/1.0 200 OK\n");
17
    sw.Flush();
18
    client.Close();
19
  }
20
}
Es hat funktioniert.

Dann habe ich mich daran gemacht den Code in C zu übersetzen, er hat 
aber leider nicht funktioniert, wenn ich 127.0.0.1:8080 aufrufe schreibt 
Firefox:
> Fehler: Verbindung unterbrochen
>
> Die Verbindung zum Server wurde zurückgesetzt, während die Seite
> geladen wurde.

Hier der C-Code und im Anhang die Ausgabe der Console:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <windows.h>
4
#include <conio.h>
5
6
int main()
7
{
8
    char buf[256];
9
    unsigned char i,cnt;
10
    WSADATA wsa;
11
    SOCKADDR_IN addr;
12
    SOCKET acceptSocket, s;
13
14
    WSAStartup(MAKEWORD(2,2),&wsa);
15
16
    acceptSocket = socket(AF_INET,SOCK_STREAM,0);
17
18
    memset(&addr,0,sizeof(SOCKADDR_IN));
19
    addr.sin_family=AF_INET;
20
    addr.sin_port = htons(8080);
21
    addr.sin_addr.s_addr=ADDR_ANY;
22
    bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
23
24
25
    printf("Wait for a connection\n");
26
    while(1)
27
    {
28
        if(listen(acceptSocket,10)==SOCKET_ERROR)
29
        {
30
            printf("Listen failed with error: %d\n", WSAGetLastError());
31
            closesocket(acceptSocket);
32
            WSACleanup();
33
            return 1;
34
        }
35
36
        s=accept(acceptSocket,NULL,NULL);
37
        printf("Verbindung zum Client hergestellt\n");
38
39
        i=0;           
40
        do      // Read until '\n'
41
        {
42
            recv(s,buf+i,1,0);
43
        }while(buf[i++]!='\n');
44
        buf[i]=0x00;
45
        printf("Recv: %s",buf);
46
47
        cnt=send(s,"HTTP/1.1 200 OK\n\n",17,0);
48
        printf("Bytes send: %d\n", cnt);
49
50
        closesocket(s);
51
        printf("\nWait for a connection\n");
52
    }
53
    closesocket(acceptSocket);
54
    WSACleanup();
55
56
    return 0;
57
}

Hat jemand eine Ahnung wie man das Problem lösen könnte?

Vielen Dank

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Probier mal
1
...
2
        printf("Recv: %s",buf);
3
4
        char* reply1 = "HTTP/1.1 200 OK\r\nContent-Type: html\r\n\r\n";
5
        char* reply2 = "<html><body>juhu klappt</body></html>\r\n";
6
7
        cnt = send(s, reply1, strlen(reply1), 0 );
8
        printf("Bytes send: %d\n", cnt);
9
        cnt = send(s, reply2, strlen(reply2), 0 );
10
        printf("Bytes send: %d\n", cnt);
11
12
        shutdown(s, 1);
13
        closesocket(s);
14
        printf("\nWait for a connection\n");
15
    }
16
 ...

Laut meinen Tests dürfte der Aufruf von shutdown der springende Punkt 
sein.
(Anstatt der 1 in dern Argumenten sollte da eigentlich SD_SEND stehen. 
Aber aus irgendeinem Grund hab ich das Makro nicht.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740481(v=vs.85).aspx
)

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Karl Heinz schrieb:
> Laut meinen Tests dürfte der Aufruf von shutdown der springende Punkt
> sein.
Genau das war's, der Rest des Codes hätte eigentlich funktioniert.

: Bearbeitet durch User
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.