gpt4 book ai didi

C http代理服务器套接字 - 没有命中

转载 作者:太空宇宙 更新时间:2023-11-04 02:50:56 25 4
gpt4 key购买 nike

我正在尝试了解 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。

但是请求没有命中这个套接字。

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

注意:这不是作业程序,我也不是学生。我只是想学习东西。此声明适用于我们可耻的可耻受访者。

最佳答案

重新编辑:

请注意检查 bind() 是否成功的重要性。有多种情况;其中一个可能是套接字处于 TIME_WAIT 状态。如果没有实际验证 bind() 并在失败时中止,则程序可能看似 正常运行。 listen() 可以顺利通过。尽管在客户端,Firefox 很可能会报告拒绝连接,但这不是给定的。


URI 方案名称

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

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

Proxy foxy

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


原始答案:-)

即使对删除的部分进行评论,我也会将其保留在这里,因为其他人可能会发现它很有用。 (而且我花了一些时间来写它。)


这里有一些问题。我会一一带走。

首先解决这个问题,然后根据需要报告。

缺少头文件和错误类型

read() , write()close() 中定义,但您不包含此文件。它可能已链接,但最好添加。

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

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

缺乏错误检查

没有错误检查它应该在的地方。规则 #1:始终检查错误!遇到麻烦而不验证请求是……一个很大的禁忌。

bind() , listen()close()返回整数。 0 是成功,-1 是错误。设置错误 errno

手册对此非常清晰易读。阅读您使用的每个功能。

包含 并使用 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. */

写语句

错误的语句:

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

首先:“收到的消息” 是 17 个字节,包括终止 null。如果你想把它写到连接上,使用类似的东西:

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
);

关于C http代理服务器套接字 - 没有命中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22284033/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com