可以通过IP访问服务器,但不能通过域名访问服务器

问题描述:

我用C写了一个简单的服务器,与您在互联网上找到的任何示例都没有多大区别。它所做的唯一的事情是在特定IP地址上监听端口80,并将任何访问重定向到其他站点。被这个软件重定向的网站是我用nginx多年来使用的个人域名。我的服务器是FreeBSD,它运行在VPS上。可以通过IP访问服务器,但不能通过域名访问服务器

我关闭了重定向站点的服务器并启动了我的自定义服务器程序。如果我在浏览器的地址栏中输入IP地址,则服务器按预期工作,并获得302状态并重定向到其他站点。如果我在地址栏中输入域名,浏览器会给出“无法连接”的错误,尽管我的服务器软件会打印它接收到的连接。山猫说,

HTTP/1.1 302临时重定向

,但只是挂在那儿。

有趣的是,在做curl -I http://example.com/回报我期望:

HTTP/1.1 302临时重定向

的Content-Length:40

地点:https://othersite.com

我不不明白为什么我可以通过IP完成这项工作,但不使用域名。

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

#define MAXLINE 4096 /*max text line length*/ 
#define SERV_PORT 80 /*port*/ 
#define LISTENQ 1 /*maximum number of client connections*/ 

int main (int argc, char **argv) 
{ 
int listenfd, connfd, n; 
pid_t childpid; 
socklen_t clilen; 
char buf[MAXLINE]; 
struct sockaddr_in cliaddr, servaddr; 

//Create a socket for the soclet 
//If sockfd<0 there was an error in the creation of the socket 
if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) { 
    perror("Problem in creating the socket"); 
    exit(2); 
} 


//preparation of the socket address 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx"); 
servaddr.sin_port = htons(SERV_PORT); 

//bind the socket 
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 

//listen to the socket by creating a connection queue, then wait for clients 
listen (listenfd, LISTENQ); 

for (; ;) { 

    clilen = sizeof(cliaddr); 
    //accept a connection 
    connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen); 

    if ((childpid = fork()) == 0) {//if it's 0, it's child process 

    //close listening socket 
    close (listenfd); 

    while ((n = recv(connfd, buf, MAXLINE,0)) > 0) { 
    send(connfd, "HTTP/1.1 302 Temporary Redirect\nContent-Length: 40\nLocation: https://example.org\n\n", 93, 0); //NOTE: I'm aware the length is wrong here due to my editing the name out. 
    } 

    exit(0); 
} 
//close socket of the server 
close(connfd); 
} 
} 
+1

这是一个EOL问题吗? Http应该使用CRLF。似乎有些客户比其他客户更宽容。 – captncraig

+0

@captncraig我没有任何问题与CRLF,并认为我读了'\ n'是你所需要的,但我用'\ r \ n'尝试过,并没有解决问题。请注意,这可以与IP地址一起使用。 – Rob

+0

铬网络选项卡显示什么有趣的?也许一个收藏夹图标请求或东西搞砸了?我不太喜欢分叉,但似乎你在一个请求后关闭了听众? – captncraig

我有这么多问题得到这个工作的原因很简单。我忘记了\ n是一个控制字符,但它的长度计为两个。

此外,该网站最初发送的浏览器会记住并自动尝试访问https版本,而我试图从http重定向的HSTS。所以这就解释了为什么我可以用l and和卷曲工作而不是其他工作。