2017-02-18 37 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协议是一个比较复杂的,如果你声称支持那么你需要支持各种额外的东西)