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

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
)

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.

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.