2013-08-29 60 views
2

我一直試圖運行我的代碼一個星期了,我不知道是什麼問題。在我的編程類中給了我們一個代碼,允許我們創建自己的tcp客戶端和/或服務器。使用該代碼,我們必須打開localhost:54321 [我們使用Apache作爲本地服務器,如果這有助於/更好地理解所發生的事情]並通過調整服務器的C代碼,頁面將顯示一條消息。C中的簡單非併發Web服務器

這裏是我的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 



int main(int argc, char **argv) 
{ 
    int listenfd,connfd; 
    struct sockaddr_in servaddr,cliaddr; 
    socklen_t len = sizeof(cliaddr); 
    char cli_ip[32]; 
    char mesg[1024]; 
    char response[1028]; 
    //char reply[] = "Hello World!"; 

    listenfd = socket(PF_INET,SOCK_STREAM,0); 
    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(54321); 

    if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0){ 
     perror(NULL); 
     exit(-1); 
    } 

    while(1){ 
    //not present in udp server 
    connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&len); 
    inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip)); 
    printf("Client %s connected. \n",cli_ip); 

    while(1){ 
     memset(mesg,0,sizeof(mesg)); 
     if(recvfrom(connfd,mesg,sizeof(mesg),0,(/*const*/ struct sockaddr *)&cliaddr,&len) > 0){ 
      printf("From %s port %d: %s",cli_ip,ntohs(cliaddr.sin_port),mesg); 
     **sprintf(response,"HTTP/1.1 200 OK \n Content-type:text/html \n Content-length: 200 \r\n <html><body> Hello, World! </body></html>"); 
     sendto(connfd,response,strlen(response),0,(const struct sockaddr *)&servaddr,len); 
     //break;** 
     } 
     else { 
     printf("Client %s disconnected.\n",cli_ip); 
     break; 
     } 
    } 

    close(connfd); 
    } 

    close(listenfd); 

    return 0; 
} 

我添加的只是線以粗體/的那些包含在雙星號。

我可以編譯它,我可以運行它,但是當我打開本地主機:54321,我說連接,但它永遠不會完成加載/連接。

如果有幫助,這是我的終端顯示當我打開本地主機:54321。

Client 127.0.0.1 connected. 
From 127.0.0.1 port 42642: GET/HTTP/1.1 
Host: localhost:54321 
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:22.0) Gecko/20100101 Firefox/22.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 

謝謝你的任何意見,建議,想法和批評。

回答

1

HTTP要求行終止CRLF(\r\n)。您的代碼只使用\n,這可能會混淆一些基本的Web客戶端。

更重要的是,您還需要在響應中使用額外的CRLF來終止標頭,並且標頭中的值必須與標頭後發送的字節數匹配。

喜歡的東西

const char* entity = "<html><body> Hello, World! </body></html>"; 
sprintf(response,"HTTP/1.1 200 OK\r\n Content-type:text/html\r\n Content-length: %d\r\n\r\n%s", strlen(entity), entity); 

應該解決這個問題。

+0

我只想確定一件事。在sendto()'後,我需要使用'break'嗎?既然你沒有提到它,而我的上面的代碼有'break'註釋掉了。 (最後,我使用它,只是想澄清它的重要性)謝謝你的意見,但! –

+0

我以前沒有通過過你的代碼那麼遠......如果你想避免重複'while(1)'循環,你需要'break'。 – simonc

1

您需要在標題和郵件正文之間留空行。

此外,你給內容長度200,但那是不正確的,所以瀏覽器正在等待其餘的數據。