代码实现功能:向固定地址发起请求得到返回页面字符,通过gethostbyname获得IP地址
代码:
//向固定IP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#define SERVPORT 80
char *Inputchar="www.12306.cn";
int htconnect(char *host, int port)
{
int white_sock;
int sockfd;
struct hostent * site;//该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列
struct sockaddr_in me;
struct sockaddr_in serv_addr;
char **pptr;
int i;
site = gethostbyname(host);//用域名或主机名获取IP地址.
//要注意的是一台服务器的域名可以对应多个不同的IP,也就是说我们通过google域名来访问google服务器时,在不同的时刻访问可能登陆的是google的不同计算机。
// 所谓的主机名字符串指的是去掉“http://”头剩下的部分,如“www.google.com”
//h_addr_list 成员 ,该成员是一个指向指针的指针类型变量,也就是一个指向指针数组的指针,在数组的每一个成员都指向一个点分的IP地址字符串,
//这些IP都与我们要转换的域名对应,那么与该域名对应的IP有多少呢?该指针数组时以NULL结尾的,
//我们可以通过这一标志遍历这个指针数组得到所有的与该域名对应的IP地址字符串。
//printf("Host name is %s\n",site);
printf("official name is %s\n",site->h_name);//例如www.google.com的规范名其实是www.l.google.com。??为何结果不是???
printf("address length: %d bytes\n\n", site->h_length);
printf("IPAddress:%s\n",inet_ntoa(*((struct in_addr*)site->h_addr)));
printf("host name alias: \n");//打印别名
for (i = 0; site->h_aliases[i]; i++)
{
printf("%s\n", site->h_aliases[i]);
}
printf("\naddress list: \n");
for (i = 0; site->h_addr_list[i]; i++)
{
if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1)
{
printf("socket error\n");
exit(0);
}
// 先清零,然后用struct sockaddr_in来填值
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVPORT);
/* h_addr_list[i]指向in_addr类型 */
serv_addr.sin_addr = *((struct in_addr *)site->h_addr_list[i]);
const char *ip = inet_ntoa(serv_addr.sin_addr);
printf("connect to %s ", ip);
// 系统调用的时候,把sockaddr_in转换成sockaddr
if (connect(sockfd, (struct sockaddr *)&serv_addr,
sizeof(struct sockaddr)) == -1) {
printf("error\n");
exit(0);
}
printf("success\n");
}
if (site==NULL)
return -2;
white_sock = socket(AF_INET,SOCK_STREAM,0);
if (white_sock <0) return -1;
memset(&me, 0, sizeof(struct sockaddr_in));
memcpy(&me.sin_addr, site-> h_addr_list[0], site-> h_length);
me.sin_family = AF_INET;
me.sin_port = htons(port);
return (connect(white_sock, (struct sockaddr *)&me,sizeof(struct sockaddr)) <0) ? -1 : white_sock;
}
int htsend(int sock, char *fmt, ...)
{
char BUF[1024];
va_list argptr;//定义一个 va_list 指针来访问参数表
va_start(argptr,fmt);//对argptr进行初始化,让它指向可变参数表里面的第一个参数
vsprintf(BUF,fmt,argptr);
va_end(argptr);
//printf(BUF); //回显
//printf("-->%s<--\n",BUF);
return send(sock,BUF,strlen(BUF),0);
}
int main(int argc,char **argv)
{
int black_sock;
int M,N;
char bugs_bunny[3];
black_sock = htconnect(Inputchar,80);//www.google.com
if (black_sock <1) return 0;
printf("循环发送请求开始\n");
printf("......\n");
M=1;N=1;
while (N==1){
if(M % 1000 == 0){printf("当前循环次数:%d \n",M); }
if(M == 10000){break;}
htsend(black_sock, "GET / HTTP/1.1\n");
htsend(black_sock, "Host: %s\n", Inputchar);
htsend(black_sock, "\n");
//htsend(black_sock, "%c ", 10);
M++;
}
printf("循环发送请求 %d 次\n",M);
printf("收到信息Start:---->\n");
while (read(black_sock, bugs_bunny, 1)> 0)
{
printf( "%c",bugs_bunny[0]);
}
printf( "收到信息End.<----\n ");
close(black_sock);
}
结果截图:
从结果可以看出,
printf("IPAddress:%s\n",inet_ntoa(*((struct in_addr*)site->h_addr)));
IP地址所显示的,其实是首个IP地址。