我已经制作了以下win32套接字程序来浏览网页 . 我使用wingw来避免依赖于任何运行时 . 为了获得ipaddresses,我通过命令提示符ping www.google.com,www.yahoo.com等网址,并在我的程序中使用这些ip addreses . 港口是80 .
我可以使用"GET /\r\n"获取谷歌,雅虎等的默认页面 . 我也可以通过使用"GET /newsite/index.aspx"来获取非默认页面,甚至是内部目录,例如http://yasini.com/newsite/index.aspx . 程序的输出是从网络服务器收到的html格式,保存在硬盘上 . 稍后在firefox中打开此文件以查看通信是如何进行的 .
我已经制作了一个测试网页http://a.domaindlx.com/trysite/hello.asp,我可以在firefox中打开它 . 然后我ping域名a.domaindlx.com并得到这个ipaddress,66.36.238.30 . 我尝试使用"GET /trysite/hello.asp"访问所述页面,但得到此回复,"No web site is configured at this address. No web site is configured at this address."
我知道上述响应是由网络服务器发送的,所以我能够连接到网络服务器 . 问题是网络服务器无法识别我尝试访问的网址 . 我使用了不同的网页,包括htm和asp,无法访问 .
当试图直接在浏览器中使用ipaddress打开网站时,我得到了同样的错误,“没有配置网站...” .
基本的难题是,为什么这些页面可以通过浏览器(如firefox)访问,而不是通过我的代码访问,当我的代码本质上是一个浏览器时,意味着与端口80上的webserver打开连接 .
#include windows.h
#include stdio.h
WSADATA ws;
int d;
char aa[1000];
struct sockaddr_in a;
SOCKET s;
int li;
void abc(char *p)
{
FILE *fp = fopen("c:\\data.htm", "a+");
fprintf(fp, "%s\n", p);
fclose(fp);
}
_stdcall WinMain (HINSTANCE i, HINSTANCE j, char * k, int l)
{
d = WSAStartup(0x101, &ws);
sprintf(aa, "WSASTARTUP = %d", d);
abc(aa);
s = socket(AF_INET, SOCK_STREAM, 0);
sprintf(aa, "SOCKET = %d", s);
abc(aa);
a.sin_family = AF_INET;
a.sin_port = htons(80);
//a.sin_addr.s_addr = inet_addr("74.125.236.145");
a.sin_addr.s_addr = inet_addr("66.36.238.30"); //a.domaindlx.com
//a.sin_addr.s_addr = inet_addr("206.225.85.18"); //www.domaindlx.com
//a.sin_addr.s_addr = inet_addr("87.248.122.122"); //www.yahoo.com
//a.sin_addr.s_addr = inet_addr("72.167.153.9"); //www.yasini.com
d = connect(s, (struct sockaddr *) &a, sizeof(a));
strcpy(aa, "GET /trysite/hello.asp\r\n");
strcat(aa, "HTTP 1.0 \r\n\r\n");
send(s, aa, sizeof(aa), 0);
li = 1;
while(li != 0)
{
li = recv(s, aa, 1000, 0);
abc(aa);
}
}
注意:请将头文件名括在尖括号的include行中,以使代码生效 . 我不得不删除属性格式的html .
3 回答
您的代码有两个问题 . 第一个是在HTTP 1.0之前应该有一个不是\ r \ n的空格 . 没有这个你发送HTTP 0.9 .
第二个问题是某些IP地址用于托管多个站点,并且需要发送主机头 .
如果您添加Host:标头,则告诉您“此地址未配置网站”的网站可能会更好 . 您对该网站的请求应如下所示:
您没有正确遵循协议 . 您想要
GET /trysite/hello.asp HTTP/1.0\r\n\r\n
请参阅here以获取完整规格 .麻烦的URL在子域上运行 . 成功的URL不是 . 许多Web服务器在同一物理IP上托管多个帐户,因此他们需要知道正在请求哪个特定域/子域才能访问正确的帐户 . 您需要在请求中包含
Host
标头 .另请注意,当您调用
send()
发送请求时,您将发送aa
缓冲区的整个1000个字节,这是错误的 . 您只需要发送您实际填写的内容 .最后,您通常不是很好地管理套接字 . 您需要更好的错误处理 .
试试这个:
我强烈建议您使用数据包嗅探器,例如Wireshark . 然后,您可以确切地看到Web浏览器(或任何其他套接字应用程序)实际发送和接收的内容 . 然后,您可以根据需要在代码中匹配它 .