C http代理服务器套接字 - 没有点击

时间:2014-03-09 15:20:42

标签: c http-proxy

我正在尝试了解HTTP代理服务器程序。我写了一个简单的基于C的套接字,它发送一个响应收到消息。请在下面找到该计划。

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

int main(){
        int recvSocketFd = 0;
        struct sockaddr_in serv_input_addr;
        char inputBuff[1024];

        memset(&serv_input_addr,'0',sizeof(serv_input_addr));
        memset(&inputBuff, '0', sizeof(inputBuff));

        recvSocketFd = socket(AF_INET,SOCK_STREAM,0);

        if(recvSocketFd <= 0){
                printf("\nError occurred while creating a socket\n");
                return -1;
        }

        serv_input_addr.sin_family = AF_INET; 
        serv_input_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        serv_input_addr.sin_port = htons(8080);
        bind(recvSocketFd, (struct sockaddr*)&serv_input_addr, sizeof(serv_input_addr));

        listen(recvSocketFd,5);

        int connFd = 0;
        int n = 0;
        int client_length = sizeof(serv_input_addr);

        while(1){
                connFd = accept(recvSocketFd, (struct sockaddr*)&serv_input_addr, &client_length);
                if(connFd <0){
                        printf("\nError in accepting messages from socket\n");
                        return -1;
                }

                n = read(connFd,inputBuff,1023);

                if(n>0){
                        printf("\nMessage : %s\n",inputBuff);   
                }
                write(connFd,"Message received",15);
                close(connFd);

        }
}

此正在运行的程序正在针对以下请求http://<localhost>:8080/test正确响应。

我尝试将其设置为代理。所以我尝试在Firefox中将其设置为手动代理http://<localhost>,并将端口设置为8080。

但请求没有达到此套接字。

如果有人可以帮助我理解这一点,那将会非常有帮助。

注意:这不是家庭作业,我不是学生。我只是想学习东西。本声明适用于我们光荣的可耻受访者。

1 个答案:

答案 0 :(得分:2)

重新编辑:

请注意在 bind()上检查成功的重要性。有各种各样的情况;其中一个可能是套接字处于TIME_WAIT状态。如果一个人实际上没有验证 bind()并且在失败时中止,程序可能看起来正在运行OK。 listen()可以无错误地传递。虽然在客户端,Firefox很可能会报告拒绝连接但它不是给定的。


URI的方案名称

在您的问题中,您声明已使用http://<localhost>进行代理设置。如果这是文字,它将失败:您不要在代理设置中包含方案名称。

请注意,Firefox不会验证主机名。例如。 a4a6®←@ł´ªĸµª5d4a"#¤&%=)(=/)=飞过,没有任何警告。

Proxy foxy

如果其中包含http://方案,则Firefox将无法连接,并且会找到 服务器


原始答案: - )

我会把它留在这里,即使对删除的部分发表评论,因为其他人可能会觉得它很有用。 (而且我用了一些时间来写它。)


这里有一些问题。我会一个接一个地拿它们。

首先修复此问题,然后根据需要进行报告。

缺少标题文件和错误类型

read()write()close()&lt; unistd.h&gt; 中定义,但您不包含此文件。它可能与之相关,但最好添加。

client_length未签署int。您可以使用unsigned int,但最好使用手册中定义的 socklen_t

read()返回 ssize_t ,而非int。也改变这个。

缺少错误检查

没有错误检查它应该在哪里。规则#1:始终检查错误!遇到麻烦而没有验证请求是......一个很大的不行。

bind()listen()close()返回int。 0表示成功,-1表示错误。出错 errno 已设置。

本手册非常清晰易读。为您使用的每个功能阅读它。

包括&lt; errno.h&gt; 并使用perror()

以最简单的方式。我们得到了堕胎而没有企图拯救:

int res;
...

res = bind(recvSocketFd, (struct sockaddr*)&serv_input_addr, sizeof(serv_input_addr));

if (res != 0) {
        perror("bind");
        return errno;
}

res = listen(recvSocketFd, 5);

if (res != 0) {
        perror("listen");
        return errno;
}

...

res = close(connFd);
if (res != 0) {
        perror("close");
        return errno;
}

write()返回 ssize_t ,成功时写入了多少字节,其他-1和 errno 设置得恰当。

res_wr = write(connFd, ...);
if (res == -1) {
        perror("write");
        return errno;
}

/* Else check if entire buffer was written, if not, act accordingly. */

写声明

Bad 语句:

write(connFd, "Message received", 15);

首先:“收到消息”是17个字节,包括终止空值。如果要将此写入连接,请使用以下内容:

const char msg_received[] = "Message received";
...

write(connFd, msg_received, sizeof(msg_received));

第二:这是你传递给客户端的东西,在你的情况下是Firefox。换句话说,Firefox会获得字符:

{ 'M', 'e', 's', 's', 'a', 'g', 'e', ' ', 'r', 'e', 'c', 'e', 'i', 'v', 'e' }

第三:在第一次读/写后立即执行 close()。 Firefox很可能会回复 连接已重置 。通常你会写你的 inputBuff ,而不是像这样的一些状态信息。

打印到stderr

作为一方不是:虽然在此示例中写入stdout 足够公平,但将错误和调试数据写入stderr是一个好习惯。保持习惯。例如:

sz_buf = read(connFd, inputBuff, BUF_SIZE - 1)

inputBuff[sz_buf] = 0x00;

fprintf(stderr,
        "\n====================== Message (%4d) ================\n"
        "%s\n"
        "--------------------------------------------------------\n"
        ,
        sz_buf, inputBuff
);