可以通过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
我不不明白为什么我可以通过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);
}
}
答
我有这么多问题得到这个工作的原因很简单。我忘记了\ n是一个控制字符,但它的长度计为两个。
此外,该网站最初发送的浏览器会记住并自动尝试访问https版本,而我试图从http重定向的HSTS。所以这就解释了为什么我可以用l and和卷曲工作而不是其他工作。
这是一个EOL问题吗? Http应该使用CRLF。似乎有些客户比其他客户更宽容。 – captncraig
@captncraig我没有任何问题与CRLF,并认为我读了'\ n'是你所需要的,但我用'\ r \ n'尝试过,并没有解决问题。请注意,这可以与IP地址一起使用。 – Rob
铬网络选项卡显示什么有趣的?也许一个收藏夹图标请求或东西搞砸了?我不太喜欢分叉,但似乎你在一个请求后关闭了听众? – captncraig