2017-02-18 69 views
0

C-SERVER:
執行外部腳本:/腳本
從存儲在 「VVV」 腳本響應和 「VVV」 被髮送到客戶端。的C-SERVER:HTTP響應缺少新線

fp = popen("/script", "r"); 
fgets(vvv, 500, fp); 

write(client_fd, vvv, sizeof(vvv) - 1); 
close(client_fd); 

內容/腳本

#!/bin/sh 
echo -e 'HTTP/1.1 200 OK\r\n'; 

測試與netcat的:

echo TEST | nc <ip> <port> 
HTTP/1.1 200 OK 

問題:它不能包含一個新行,因此它可以使用Web瀏覽器。

C-SERVER:

#include <arpa/inet.h> 
#include <err.h> 
#include <string.h> 

char inn[100]; 

FILE *fp; 
char vvv[100]; 

int main() 
{ 
    int one = 1, client_fd; 
    struct sockaddr_in svr_addr, cli_addr; 
    socklen_t sin_len = sizeof(cli_addr); 

    int sock = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock < 0) 
    err(1, "can't open socket"); 

    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); 

    int port = 85; 
    svr_addr.sin_family = AF_INET; 
    svr_addr.sin_addr.s_addr = INADDR_ANY; 
    svr_addr.sin_port = htons(port); 

    if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) { 
    close(sock); 
    err(1, "Can't bind"); 
    } 

    listen(sock, 5); 
    while (1) { 
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len); 
    size_t bytesRead = read(client_fd,inn,sizeof(inn) - 1); 

    fp = popen("/script", "r"); 
    fgets(vvv, 500, fp); 
    printf(vvv); 


    write(client_fd, vvv, sizeof(vvv) - 1); 
    close(client_fd); 
    } 
} 
+0

我太新C.我甚至不會知道如何做類似** VVV = VVV +「/ N」 **如果那是當然的答案。 – Vorn3rala

+0

好,那會不會是你的 –

+0

緩衝'vvv'爲100個字節,但你給限500〜'fgets',爲什麼? –

回答

0

請注意,HTTP標頭和內容由空行分隔。如果你根本沒有提供任何內容,情況也是如此。

另外echo已經在行後追加換行符。使用printf代替:

#!/bin/sh 
printf 'HTTP/1.1 200 OK\r\n'; 
printf '\r\n'; 
printf 'Content'; # provide some content 

但現在,你需要從fp讀取多條線路,這需要。添加額外的循環,從fp閱讀每一行:

... 

while (1) { 
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len); 
    size_t bytesRead = read(client_fd,inn,sizeof(inn) - 1); 

    fp = popen("/script", "r"); 

    while (!feof(fp)) { 
    // be careful here to use `sizeof` instead of the harcoded `500` 
    fgets(vvv, sizeof(vvv), fp); 
    // only write the number of bytes read 
    write(client_fd, vvv, strlen(vvv)); 
    printf(vvv); 
    } 

    close(client_fd); 
} 

... 

也可以考慮使用fread而不是fgets防止長行截斷。

0

再次,請閱讀文檔。 fgets reads:

最多隻比從stream指向的流中指定的字符數少n個指向s指向的數組。 在換行符(保留)之後或在文件結束之後不會讀取其他字符。在讀入數組的最後一個字符後立即寫入空字符。

HTTP響應必須包含 CRLF換行符 - 第一終止狀態線和第二分離從所述主體的狀態行:

HTTP/1.0 200 OK\r\n 
\r\n 

腳本應當同樣產生這些換行符這樣:

echo -e 'HTTP/1.1 200 OK\r\n\r\n'; 

但是你fgets電話停短 - 它讀取,直到只有第一個字符\n。其實你不應該使用fgets可言,而是使用fread,直到EOF滿足,像

fp = popen("/script", "r"); 
while (!feof(fp) && !ferror(fp)) { 
    size_t bytes_read = fread(vvv, 1, sizeof(vvv), fp); 
    if (read) { 
     write(client_fd, vvv, bytes_read); 
    } 
} 
pclose(fp); // must *absolutely* close the pipe with pclose 

(PS HTTP/1.1協議是一個比較複雜的,如果你聲稱支持那麼你需要支持各種額外的東西)