我用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);
}
}
這是一個EOL問題嗎? Http應該使用CRLF。似乎有些客戶比其他客戶更寬容。 – captncraig
@captncraig我沒有任何問題與CRLF,並認爲我讀了'\ n'是你所需要的,但我用'\ r \ n'嘗試過,並沒有解決問題。請注意,這可以與IP地址一起使用。 – Rob
鉻網絡選項卡顯示什麼有趣的?也許一個收藏夾圖標請求或東西搞砸了?我不太喜歡分叉,但似乎你在一個請求後關閉了聽衆? – captncraig