代码如下
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(int c, char **v)
{
//\r表示回车,\n表示换行
//发送这些信息,应该相当于发送了一个GET请求。利用socket来发送get请求
const char query[] =
"GET http://www.ncu.edu.cn/ HTTP/1.0\r\n"
"Host: www.ncu.edu.cn\r\n"
"Accept:*/*\r\n"
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)\r\n"
"Accept-Language:zh-cn\r\n"
"\r\n";
const char hostname[] = "www.ncu.edu.cn";
//套接字地址结构
struct sockaddr_in socketAddr_in;
//对一个主机的描述,有地址,主机名等
struct hostent *baiduhost;
const char *cp;
int fd;
ssize_t n_written, remaining;
char buf[1024];
/* 寻找主机IP地址.*/
baiduhost = gethostbyname(hostname); //gethostbyname是阻塞的,得不到地址不返回
if (!baiduhost) {
fprintf(stderr, "Couldn't lookup %s: %s", hostname, hstrerror(h_errno));
return 1;
}
if (baiduhost->h_addrtype != AF_INET) {
fprintf(stderr, "No ipv6 support, sorry.");
return 1;
}
fd = socket(AF_INET, SOCK_STREAM, 0);
printf("fd-----> %d\n",fd);
if (fd < 0) {
perror("socket");
return 1;
}
/* 连接远程主机服务器. */
socketAddr_in.sin_family = AF_INET;
socketAddr_in.sin_port = htons(80);
socketAddr_in.sin_addr = *(struct in_addr*)baiduhost->h_addr;
//connect函数,从进程到内核传递套接字地址结构的函数,第二个参数为socket指针,第三个参数为大小
if (connect(fd, (struct sockaddr*) &socketAddr_in, sizeof(socketAddr_in))) {
perror("connect");
close(fd);
return 1;
}
//使用send和recv发送和接收数据时,都使用无限循环
cp = query;
remaining = strlen(query);
while (remaining) {
n_written = send(fd, cp, remaining, 0); //send函数,成功则返回实际传送出去的字符数,失败返回-1
if (n_written <= 0) {
perror("send");
return 1;
}
remaining -= n_written; //remaining 不为0表明还没有发送完数据
cp += n_written;
}
//将返回结果读入到buf中,利用循环来实现读取所有的数据
while (1) {
ssize_t result = recv(fd, buf, sizeof(buf), 0);
if (result == 0) { //result返回0,表示读入完毕,跳出循环
break;
} else if (result < 0) {
perror("recv");
close(fd);
return 1;
}
fwrite(buf, 1, result, stdout); //写入文件或者标准输出
}
close(fd);
return 0;
}
运行效果: